代码之家  ›  专栏  ›  技术社区  ›  acmoune

scala:可以调用不带括号的函数吗?[副本]

  •  0
  • acmoune  · 技术社区  · 6 年前

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

    它们很难搜索,因为它们大多数/所有都是纯符号,因此在不知道概念名称的情况下很难搜索。

    待办事项:

    • 隐式转换
    • _ 匿名函数的语法
    • 其他我忘记的事情
    0 回复  |  直到 12 年前
        1
  •  58
  •   Mifeet Alexander    10 年前

    基础知识:

    • a b 相当于 a.b
    • a b c 相当于 a.b(c) ,除非 b 结束于 : 是的。在这种情况下, 甲、乙、丙 相当于 c.b(a)
    • a(b) 相当于 a.apply(b) 这就是为什么匿名函数的以下定义是相同的: 值平方1=(x:int)=>x 十 val square2=新函数1[int,int]{ def apply(x:int)=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 在类/对象中,scala创建方法 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 ,和 !a

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

      class 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
      
        2
  •  19
  •   IttayD    15 年前

    除了jaxkson的回答:

    • type F[A,B] 可用作 A F B 是的。

    例如:

    type ->[A,B] = (A,B)
    def foo(f: String -> String)
    
    • 使用 => type 在方法定义中,编译器将表达式包装在函数thunk中的方法调用中。

    例如

    def until(cond: => Boolean)(body: => Unit) = while(!cond) body
    
    var a = 0
    until (a > 5) {a += 1}
    
        3
  •  18
  •   Community CDub    8 年前

    特殊类:元组和符号

    如所述 Rahul G ,元组和符号有一个稍微特殊的语法。

    • 符号:语法 'x Symbol("x")
    • 元组: (p1,p2,..,pn) 是case类的缩写 Tuplen[T1,T2,..,Tn](p1,p2,..,pn)

    例如,下面两个是等价的。

    val tuple1 = ("Hello",1)
    val tuple2 = Tuple2[String,Int]("Hello",1)
    
        4
  •  14
  •   Peter Mortensen icecrime    12 年前

    提取器:

    提取器有两种方法, unapply unapplySeq 是的。它们用于多变量赋值和模式匹配。

    • 第一个用例是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 声明。当然,如果你有更好的例子,请在下面留言

    • 一般情况下 不合时宜 接受一些固定数量的参数并返回 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?")
      }
      

    注: Case classes 做所有这些 apply / 不合时宜 为您定义(以及其他东西),因此在可能节省时间和减少代码的情况下使用它们。

    • 不易分析 是的。其工作原理与 不合时宜 如上所述,但它必须返回 Option 某种序列的。

    举个简单的例子,

    scala> List.unapplySeq(List(1,2,3))
    res2: Some[List[Int]] = Some(List(1, 2, 3))
    
        5
  •  5
  •   Aza vadipp    12 年前

    匿名函数:

    _ + _ (a, b) => a + b

        6
  •  5
  •   Erik Kaplun    11 年前

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

    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
      ...
    }
    
    推荐文章