scala =>符号含义总结
来源:互联网 发布:linux如何挂载磁盘 编辑:程序博客网 时间:2024/05/30 02:24
It has several meanings in Scala, all related to its mathematical meaning as implication.
- In a value, it introduces afunction literal(通译为匿名函数,有时候也叫函数显式声明,函数字面量), or lambda(参考lambda表达式的文章,其实也是匿名函数).e.g. the bit inside the curly braces in:
List(1,2,3).map {(x: Int) => x * 2 }
- In a type, with symbols on both sides of the arrow (e.g.
A => T
,(A,B) => T
,(A,B,C) => T
, etc.) it's sugar(syntactic sugar语法糖) forFunction<n>[A[,B,...],T]
, that is, a function that takes parameters of typeA[,B...]
, and returns a value of typeT
.(语法糖通过更简洁的语法达到目的,直接把所需要的参数、类型、函数最简化,然后把解析的工作交给编译器来完成,这步称为去糖化。例如,(A,B)=>T,包含了函数,参数以及类型,实际上是一个匿名函数,func(A,B,T)或者func(A T,B T))。
=> is syntactic sugar for creating instances of functions. Recall that every function in scala is an instance of a class.
For example, the type Int => String, is equivalent to the type Function1[Int,String] i.e. a function that takes an argument of type Int and returns a String.
scala> val f: Function1[Int,String] = myInt => "my int: "+myInt.toString
f: (Int) => String = <function1>
scala> f(0)
res0: String = my int: 0
scala> val f2: Int => String = myInt => "my int v2: "+myInt.toString
f2: (Int) => String = <function1>
scala> f2(1)
res1: String = my int v2: 1
scala> val f2: Function2[Int,Int,String] = (myInt1,myInt2) => "This is my function to transfer " + myInt1 + " and " + myInt2 + " as a string component."
f2: (Int, Int) => String = <function2>
scala> f2(1,2)
res6: String = This is my function to transfer 1 and 2 as a string component.
scala> val f22:(Int,Int)=>String = (myInt1,myInt2) => "This is my function to transfer " + myInt1 + " and " + myInt2 + " as a string component."
f22: (Int, Int) => String = <function2>
scala> f22(2,4)
res7: String = This is my function to transfer 2 and 4 as a string component.
Here myInt is binded to the argument value passed to f and f2.
() => T is the type of a function that takes no arguments and returns a T. It is equivalent to Function0[T]. () is called a zero parameter list I believe.
scala> val f: () => Unit = () => { println("x")}
f: () => Unit = <function0>
scala> f()
x
scala> val f2: Function0[Unit] = () => println("x2")
f: () => Unit = <function0>
scala> f2()
x2
f: () => Unit = <function0>
scala> f()
x
scala> val f2: Function0[Unit] = () => println("x2")
f: () => Unit = <function0>
scala> f2()
x2
As the most simplified answer, you can substitute whatever is on the left-hand side of => with the word "LEFT" and whatever is on the right-hand side with the word "RIGHT".
Then, the meaning of "LEFT => RIGHT" becomes:
Take LEFT then do RIGHT.
This means that if you have a "()=>" that you can take nothing (that is, no parameters) and then do whatever is on the right-hand side.
This is the most common meaning.
- Empty parens on the left hand side (e.g.
() => T
) indicate that the function takes no parameters (also sometimes called a "thunk");
定时器的示例程序还可以做一些改进。首先,timeFlies 函数只被用过一次,也就是当做回调函数传给 oncePerSecond 的时候,对于这种函数,在用到的时候即时构造更合理,因为可以省去定义和命名的麻烦,在 Scala 中,这样的函数称为匿名函数(anonymousfunctions),也就是没有名字的函数。使用匿名函数代替 timeFlies 函数后的程序代码如下:
object TimerAnonymous {
def oncePerSecond(callback: () => Unit) {
<span style="white-space:pre"> </span>while (true) { callback(); Thread sleep 1000 }
}
def main(args: Array[String]) {
<span style="white-space:pre"> </span>oncePerSecond(() =>
<span style="white-space:pre"> </span>println("time flies like an arrow..."))
}
}
代码中的右箭头‘=>’表明程序中存在一个匿名函数,箭头左边是匿名函数的参数列表,右边是函数体。在本例中,参数列表为空(箭头左边是一对空括号),而函数体和改造前定义的 timeFlies 函数保持一致。
函数求值有两种策略,一种是传值调用,一种是传名调用,其中编译器的"传名调用"实现,往往是将参数放到一个临时函数之中,再将这个临时函数传入函数体。这个临时函数就叫做 Thunk 函数,也称为柯里化。
function f(m){
return m * 2;
}
f(x + 5);
// 等同于
var thunk = function () {
return x + 5;
};
function f(thunk){
return thunk() * 2;
}
- Empty parens on the right hand side denote that it returns
()
— the sole value of typeUnit
, whose name can also be written()
—confused yet? :)A function that returns Unit is also known as a procedure, normally a method that's called only for itsside effect.
Scala对于不返回值的函数有特殊的表示法。如果函数体包含在花括号当中但没有前面的=号,那么返回值类型就是Unit。这样的函数被称做过程(procedure)。过程不返回值,我们调用它仅仅是为了它的副作用。例如:
scala> def box(s: String) {
| var border = "-" * s.length + "--\n"
| println(border + "|" + s + "|\n" + border)
| }
box: (s: String)Unit
scala> box("Hello")
-------
|Hello|
-------
| var border = "-" * s.length + "--\n"
| println(border + "|" + s + "|\n" + border)
| }
box: (s: String)Unit
scala> box("Hello")
-------
|Hello|
-------
关于side effect的翻译
点击了一个按钮,用户所期待的行为不叫“side effects”,用户没有期待的行为才叫“side effects”。
函数一般认为是没有状态的,每次用相同的输入调用时应当给出相同的输出,且不会影响程序的其它部分。如果函数对程序的状态有影响,这种影响就叫作“side effects”。
总之,“side effects”指的就是那些本不应有或者用户意料之外的作用,翻译成“副作用”我觉得挺恰当的。它可以看成医学上“副作用”一词的合理引申。
举个简单的例子好了:
int counter = 0;
// with side effectint incCounter() {
counter += 1;
return counter;}
// without side effectint incNumber(int m) {
return m + 1;}
// with side effectint incCounter() {
counter += 1;
return counter;}
// without side effectint incNumber(int m) {
return m + 1;}
incCounter 修改了它 scope 以外的东西,它跑过一遍之后会修改外部环境,我们讲这叫 side effect。intNumber 跑完之后本来什么样还是什么样,这就叫没有 side effects。翻成「副作用」没有问题。
- In the type declaration for a method or function parameter, with no symbol on the left hand side (e.g.
def f(param: => T)
) it's a "by-name parameter"(传名参数,或者翻译为叫名参数), meaning that is evaluated every time it's used within the body of the function, and not before. Ordinary"by-value" parameters (传值参数)are evaluated before entry into the function/method.
By-Value参数,我们都比较熟悉,参数在进入函数前就进行计算,最后传入的最终的计算结果。
By-Name参数,表示参数在进入函数后,每次在函数体内调用的时候才会计算。
def myByName1(param: () => Boolean): Unit = {
println("start")
println(param) //println(param.apply())也可以
println("end")
}
//要实现传名函数,要定义的类型开始于“=>”,而不是“() =>”。
//myByName1{7>9}不会有效,因为缺少“() =>”
myByName1{() =>
println("enter")
7 > 9
}
- In a
case
clause(case子句), they separate the pattern (and optional guard) from the result expression, e.g.case x => y
.
switch
val friend =
firstArg match {
case "salt" => "pepper"
case "chips" => "salsa"
case "eggs" => "bacon"
case _ => "huh?"
}
exception
try {
val file = new FileReader("input.txt")
} catch {
case ex: FileNotFoundException => ex.printStackTrace()
case ex: IOException => //ex.printStackTrace()可以省略
} finally {
file.close()
}
这个try-catch表达式的行为与其它语言中的异常处理一致。程序体被执行,如果抛出异常,每个catch子句依次被尝试。本例中,如果异常是FileNotFoundException,那么第一个子句将被执行。如果是IOException类型,第二个子句将被执行。如果都不是,那么try-catch将终结并把异常上升出去。
注意
你将很快发现与Java的一个差别是Scala里不需要你捕获检查异常:checked exception,或把它们声明在throws子句中。如果你愿意,可以用ATthrows标注声明一个throws子句,但这不是必需的。
参考文档:
http://www.aboutyun.com/thread-11934-1-1.html
http://www.zhihu.com/question/30779564
https://en.wikipedia.org/wiki/Syntactic_sugar
http://www.zhihu.com/question/20125256
http://blog.csdn.net/qinzhaokun/article/details/50504423
http://www.ruanyifeng.com/blog/2015/05/thunk.html
http://clayz.iteye.com/blog/1623035
http://www.aiuxian.com/article/p-2792563.html
0 0
- scala =>符号含义总结
- Scala各种符号的含义
- 【Scala一】Scala各种符号的含义
- 【Scala系列一】Scala各种符号的含义
- Scala中的=>符号
- Scala的“=>”符号简介
- scala =>符号的使用
- scala符号
- scala 符号
- 符号含义
- scala符号<:和: =>以及_*等
- Scala => 用法总结
- scala下划线的含义
- scala中的下划线含义
- scala _下划线含义
- UML符号含义
- uml符号含义
- UML符号含义
- 关于C#的委托
- iOS Photos.framework 使用
- c++多个源文件共用一个全局变量(extern 的用法)
- python装饰器详解
- Delphi构造函数和析构函数
- scala =>符号含义总结
- 深度探索new和delete
- Log4Net简单应用
- 雅虎团队经验:网站页面性能优化的34条黄金守则
- 从源码分析RxJava在Android里线程切换的实现
- 解决UnicodeEncodeError: 'ascii' codec can't encode characters in position
- 关于fresco的属性介绍
- Jprofiler9.2使用介绍
- 不完全函数(待处理)