Jakie są wszystkie instancje cukru składniowego w Scali?
Jakie są wszystkie instancje cukru składniowego w Scali?
Trudno ich szukać, ponieważ większość / wszystkie z nich są czysto symbolami i dlatego trudno ich szukać bez znajomości nazwy pojęcia.TODO:
- Implicit conversions
-
_
składnia funkcji anonimowych - inne rzeczy, o których zapominam
6 answers
Podstawy:
-
a b
jest równoważnea.b
-
{[4] } jest równoważne
a.b(c)
, z wyjątkiem sytuacji, gdyb
Kończy się na:
. W takim przypadkua b c
jest równoważnec.b(a)
-
a(b)
jest równoważnea.apply(b)
dlatego następujące definicje funkcji anonimowych są identyczne: val square1 = (X: Int) = > x x val square2 = new function 1[Int, Int] { def apply(x: Int) = x x }Kiedy dzwonisz
square1(y)
, jesteś wywołaniesquare1.apply(y)
któresquare1
musi mieć określone przezFunction1
trait (orFunction2
, itd...) a(b) = c
jest równoważnea.update(b,c)
podobnie, {[19] } jest równoważnea.update(b,c,d)
i tak dalej.-
a.b = c
jest równoważnea.b_=(c)
. Podczas tworzeniaval
/var
x
w klasie/obiekcie Scala tworzy dla Ciebie metodyx
ix_=
. Możesz je zdefiniować samodzielnie, ale jeśli zdefiniujeszy_=
musisz zdefiniować zdefiniowaćy
, inaczej nie będzie kompilowany, dla przykład,scala> val b = new Object{ def set_=(a: Int) = println(a) } b: java.lang.Object{def set_=(Int): Unit} = $anon$1@17e4cec scala> b.set = 5 <console>:6: error: value set is not a member of java.lang.Object{def set_=(Int): Unit} b.set = 5 ^ scala> val c = new Object{ def set = 0 ; def set_=(a:Int) = println(a) } c: java.lang.Object{def set: Int; def set_=(Int): Unit} = $anon$1@95a253 scala> c.set = 5 5
-a
odpowiadaa.unary_-
podobnie dla+a
,~a
, oraz!a
-
a <operator>= b
, gdzie<operator>
jest pewnym zbiorem znaków specjalnych, jest odpowiednikiema = a <operator> b
tylko jeślia
nie ma metody<operator>=
, na przykładclass test(val x:Int) { def %%(y: Int) = new test(x*y) } var a = new test(10) a.x // 10 a %%= 5 //Equivalent to a = a %% 5 a.x // 50
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-28 15:05:57
Oprócz odpowiedzi Jaxksona:
-
type F[A,B]
może być używany jakoA F B
.
Na przykład:
type ->[A,B] = (A,B)
def foo(f: String -> String)
- użycie
=> type
w definicji metody powoduje, że kompilator zawija wyrażenia wewnątrz wywołania metody w funkcję thunk.
Na przykład
def until(cond: => Boolean)(body: => Unit) = while(!cond) body
var a = 0
until (a > 5) {a += 1}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-19 17:38:09
Klasy specjalne: krotki i symbole
Jak wspomniano przez Rahul g , krotki i symbole mają nieco specjalną składnię.
- Symbole: składnia {[1] } jest skrótem od
Symbol("x")
- krotki:
(p1,p2,..,pn)
to skrót od klasy caseTuplen[T1,T2,..,Tn](p1,p2,..,pn)
Na przykład następujące dwa są równoważne.
val tuple1 = ("Hello",1)
val tuple2 = Tuple2[String,Int]("Hello",1)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:09:59
Ekstraktory:
Istnieją dwie metody stosowane dla ekstraktorów, unapply
i unapplySeq
. Są one używane w wielu przypisaniach zmiennych i dopasowywaniu wzorców.
-
Pierwszy przypadek użycia polega na tym, że unaply pobiera obiekt, do którego ma pasować i zwraca
Boolean
na podstawie tego, czy pasuje, czy nie, na przykładtrait Gender trait Male extends Gender trait Female extends Gender object Male extends Male object Female extends Female class Person(val g: Gender, val age: Int) object Adult { def unapply(p: Person) = p.age >= 18 } def check(p: Person) = p match { case Adult() => println("An Adult") case _ => println("A Child") } //Will print: An Adult since Adult.unapply returns true. check(new Person(Female, 18)) //Will print: A Child as it falls through to the _ case. check(new Person(Male, 17))
Szczerze mówiąc, nie rozumiem celu powyższej składni, ponieważ można to zrobić prawie tak samo łatwo, umieszczając kod w oświadczeniach case
. Oczywiście, jeśli masz lepszy przykład, zostaw komentarz poniżej
-
Ogólny przypadek, w którym
unapply
pobiera pewną stałą liczbę parametrów i zwraca {[8] } dla pojedynczego parametru lubOption[(p1,p2,...)]
dla wielokrotności, tj. krotkę z dopasowanymi wartościami, na przykład, kontynuując powyższy kod:object Person { def apply(g: Gender, age: Int) = new Person(g, age) def unapply(p: Person) = if(p.age < 0) None else Some((p.g, p.age)) } //Using Person.apply as described in the Basics section val alice = Person(Female, 30) val bob = Person(Male, 25) //This calls Person.unapply(alice), which returns Some((Female, 30)). //alice_gender is assigned Female and alice_age 30. val Person(alice_gender, alice_age) = alice bob match { //Calls Person.unapply(bob), but sees that g is Male, so no match. case Person(Female, _) => println("Hello ma'am") //Calls Person.unapply(bob) and assigns age = bob.age, but it doesn't pass //the 'if' statement, so it doesn't match here either. case Person(Male, age) if age < 18 => println("Hey dude") //So bob falls through to here case _ => println("Hello Sir") } Person(Male,-1) match { //Person.unapply(Person.apply(Male,-1)) returns None because p.age < 0. //Therefore this case will not match. case Person(_, _) => println("Hello person") //Thus it falls through to here. case _ => println("Are you Human?") }
Uwaga: klasy Case wykonują wszystkie te apply
/unapply
definicje dla Ciebie (jak i innych rzeczy) więc używaj ich kiedy możliwe, aby zaoszczędzić czas i zmniejszyć kod.
-
unapplySeq
. Działa to podobnie dounapply
Jak wyżej, z tym że musi zwrócićOption
pewnego rodzaju sekwencję.
Jako szybki przykład,
scala> List.unapplySeq(List(1,2,3))
res2: Some[List[Int]] = Some(List(1, 2, 3))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-16 16:53:03
Context ogranicza desugar do implicit
parametrów, np. rozważmy funkcję wykorzystującą klasę typu Monoid
:
def suml[T: Monoid](xs: List[T]) = {
val T = implicitly[Monoid[T]]
xs.foldLeft(T.mzero)(T.mplus)
}
Gdzie : Monoid
część jest związana z kontekstem, zostaje przetłumaczona na:
def suml[T](xs: List[T])(implicit evidence$1: Monoid[T]]) = {
...
}
Dlatego też kompiluje się:
def suml[T: Monoid](xs: List[T]) = {
val T = evidence$1
...
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-23 13:57:01
Funkcje anonimowe:
_ + _
jest skrótem od (a, b) => a + b
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-04 22:07:33