Scala中语法糖的所有实例是什么?

Jac*_*vis 63 scala syntactic-sugar

Scala中语法糖的所有实例是什么?

它们很难搜索,因为它们中的大部分/全部都是纯符号,因此在不知道概念名称的情况下难以搜索.

去做:

  • 隐含的转换
  • _ 匿名函数的语法
  • 其他我忘记的事情

Jac*_*vis 59

基本:

  • a b 相当于 a.b
  • a b c相当于a.b(c),除非在b结束时:.在那种情况下,a b c相当于c.b(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等同于a.update(b,c),a(b,c) = d等同于a.update(b,c,d)等等.

  • a.b = c相当于a.b_=(c).当你创建一个val/ var x在类/对象,斯卡拉创建方法xx_=为您服务.您可以定义这些自己,但如果你定义y_=必须定义y,否则将无法编译,例如,

    val square1 = (x: Int) => x*x
    val square2 = new Function1[Int,Int] {
        def apply(x: Int) = x*x
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • -a对应于a.unary_-同样为+a,~a,和!a

  • a <operator>= b,其中<operator>一些组的特殊字符,相当于a = a <operator> b 只有如果a没有<operator>=方法,例如,

    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
    
    Run Code Online (Sandbox Code Playgroud)


Itt*_*ayD 19

除了Jaxkson的回答:

  • type F[A,B]可以用作A F B.

例如:

type ->[A,B] = (A,B)
def foo(f: String -> String)
Run Code Online (Sandbox Code Playgroud)
  • 使用=> type方法定义使得函数的thunk方法调用内部编译器包表达式.

例如

def until(cond: => Boolean)(body: => Unit) = while(!cond) body

var a = 0
until (a > 5) {a += 1}
Run Code Online (Sandbox Code Playgroud)


Jac*_*vis 18

特殊类:元组和符号

正如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)
Run Code Online (Sandbox Code Playgroud)


Jac*_*vis 14

提取:

提取器有两种方法,unapplyunapplySeq.它们用于多个变量赋值和模式匹配.

  • 第一个用例是unapply获取它应该匹配的对象,并Boolean根据它是否匹配返回a ,例如,

    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))
    
    Run Code Online (Sandbox Code Playgroud)

老实说,我并没有真正达到上述语法的目的,因为只需将代码放在case语句中就可以轻松完成.当然,如果你有一个更好的例子,请在下面留言

  • 一般情况下,unapply取一些固定数量的参数并返回Option[T]一个参数或一个Option[(p1,p2,...)]多个参数,即一个具有匹配值的元组,例如,从上面的代码继续:

    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?")
    }
    
    Run Code Online (Sandbox Code Playgroud)

注意: Case类为您执行所有这些apply/ unapply定义(以及其他内容),因此请尽可能使用它们以节省时间并减少代码.

  • unapplySeq.这类似于unapply上面的工作,除了它必须返回Option某种序列.

作为一个简单的例子,

scala> List.unapplySeq(List(1,2,3))
res2: Some[List[Int]] = Some(List(1, 2, 3))
Run Code Online (Sandbox Code Playgroud)


vad*_*ipp 6

匿名函数:

_ + _ 是短的 (a, b) => a + b


Eri*_*lun 6

上下文将desugar限制为implicit参数,例如考虑利用Monoid类型类的函数:

def suml[T: Monoid](xs: List[T]) = {
  val T = implicitly[Monoid[T]]
  xs.foldLeft(T.mzero)(T.mplus)
}
Run Code Online (Sandbox Code Playgroud)

其中: Monoid部分是结合上下文,被翻译为:

def suml[T](xs: List[T])(implicit evidence$1: Monoid[T]]) = {
  ...
}
Run Code Online (Sandbox Code Playgroud)

因此以下编译:

def suml[T: Monoid](xs: List[T]) = {
  val T = evidence$1
  ...
}
Run Code Online (Sandbox Code Playgroud)