斯卡拉语法糖的所有实例是什么?
斯卡拉语法糖的所有实例是什么?
他们很难search,因为大部分/全部都是纯粹的符号,因此在不知道概念名称的情况下很难search。
去做:
- 隐式转换
-
_
匿名函数的语法 - 其他的事情,我忘了
基本:
-
ab
相当于ab
-
abc
相当于ab(c)
,除非b
结束于:
。 在这种情况下,abc
相当于cb(a)
-
a(b)
相当于a.apply(b)
这就是为什么匿名函数的下列定义是相同的:val square1 =(x:Int)=> x x val square2 = new Function1 [Int,Int] {def apply(x:Int)= x x}当调用
square1(y)
,实际上是调用square1.apply(y)
,square1
必须具有Function1
特征(或Function2
等)所指定的值。 -
a(b,c) = d
等价于a.update(b,c,d)
等等。 -
ab = c
相当于a.b_=(c)
。 当你在一个Class / Object中创build一个val
/var
x
时,Scala会为你创build方法x
和x_=
。 你可以自己定义这些,但是如果你定义了y_=
你必须定义y
或者它不会被编译,例如,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
对应于a.unary_-
对于+a
,a.unary_-
和!a
-
a <operator>= b
,其中<operator>
是一些特殊字符集合, 仅当a
没有<operator>=
方法时才相当于a = a <operator> b
,例如,class test(val x:Int) { def %%(y: Int) = new test(x*y) } var a = new test(10) ax // 10 a %%= 5 //Equivalent to a = a %% 5 ax // 50
除了Jaxkson的回答:
-
type F[A,B]
可以用作AFB
。
例如:
type ->[A,B] = (A,B) def foo(f: String -> String)
- 使用
=> type
方法定义使编译器将函数thunk中的方法调用内部的expression式包装起来。
例如
def until(cond: => Boolean)(body: => Unit) = while(!cond) body var a = 0 until (a > 5) {a += 1}
特殊类:元组和符号
正如Rahul G所提到的,元组和符号的语法略有特殊。
- 符号:语法
'x
是Symbol("x")
简写 - 元组:
(p1,p2,..,pn)
是一个案例类Tuplen[T1,T2,..,Tn](p1,p2,..,pn)
例如,以下两个是等价的。
val tuple1 = ("Hello",1) val tuple2 = Tuple2[String,Int]("Hello",1)
提取:
有两种方法用于提取器,不适用和不unapplySeq
。 这些用于多个variables赋值和模式匹配。
-
第一个用例是unapply取其匹配的对象,并根据它是否匹配返回一个
Boolean
,例如,trait 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))
老实说,我没有真正达到上述语法的目的,因为只要将代码放在case
语句中就可以轻松完成。 当然,如果你有一个更好的例子,请在下面留言
-
一般情况下,
unapply
需要一些固定数量的参数,并返回单个参数的Option[T]
或者返回多个参数的Option[(p1,p2,...)]
,即一个具有匹配值的Tuple例如,从上面的代码继续:object Person { def apply(g: Gender, age: Int) = new Person(g, age) def unapply(p: Person) = if(p.age < 0) None else Some((pg, 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?") }
注意: Case类为你做了所有这些apply
/不apply
定义(以及其他东西),所以尽可能使用它们来节省时间和减less代码。
-
unapplySeq
。 这与上面的不适用相似,除了它必须返回某种序列的Option
。
作为一个简单的例子,
scala> List.unapplySeq(List(1,2,3)) res2: Some[List[Int]] = Some(List(1, 2, 3))
匿名function:
_ + _
是(a, b) => a + b
缩写
上下文边界parsing为implicit
参数,例如考虑一个利用Monoid
types的函数:
def suml[T: Monoid](xs: List[T]) = { val T = implicitly[Monoid[T]] xs.foldLeft(T.mzero)(T.mplus) }
其中: Monoid
部分是一个上下文绑定,被转换为:
def suml[T](xs: List[T])(implicit evidence$1: Monoid[T]]) = { ... }
所以下面也编译一下:
def suml[T: Monoid](xs: List[T]) = { val T = evidence$1 ... }