为什么按名称调用的参数期望 Int 类型的参数而不是 () => Int
Why call-by-name parameter expect parameter of type Int instead of () => Int
我对在 Scala 中使用按名称调用参数有点困惑。请帮助我了解这里发生了什么。考虑以下使用按名称调用参数的示例:
def param = {println("Param evaluates"); 40}
def lazyEval(x: => Int) = {
println("lazy");
x
}
val s = lazyEval(param + 2)
// s = 42
关于这个我有几个相互关联的问题:
lazyEval
方法需要=> Int
类型的参数,那么为什么param + 2
操作是合法的呢?为什么我们可以在调用 lazyEval
方法时将整数 2 添加到类型为 => Int
的对象(我的理解是 <function0>
)?正如 IDE 提示我的那样,lazyEval
函数需要 Int
类型的参数而不是 => Int
(到底是什么?)。
为什么将回调类型从 => Int
更改为 () => Int
代码无法编译?这两种类型不同吗?我虽然简短的版本 ('=> Int') 只是一个语法糖。
在尝试了一些代码之后,我终于可以更改代码以便它可以使用 () => Int
进行编译。这种方式对我来说更直观。
.
def param = {println("Param evaluates"); 40}
def lazyEval(x: () => Int) = { // changed type to '() => Int'
println("lazy");
x() // explicitly calling function using parentheses '()'
}
val s = lazyEval(param _) // adding underscore after method name and removing `+2`
这个版本和第一个版本(回调 => Int
类型)有什么区别?为什么在这个版本中我们不能将值为 2
的整数和 param
函数相加(我的意思是这个 lazyEval(param _ + 2)
)?方法名称后的下划线是什么意思? (我猜它曾经传递方法本身,而不是 return 值)
感谢帮助
so why param + 2 operation is legal? Why we can add integer 2 to object with type => Int
我们可以将 2
添加到 param
,因为它的计算结果是 Int
,您正在添加 Int
和 Int
。 param
不是一个函数 => Int
,它是一个方法,所以 param + 2
是 => Int
。 IE。计算结果为 Int
.
的表达式
Why after changing callback type from => Int to () => Intcode doesn't compile? Is this 2 types are different? I though the short version ('=> Int') is just a syntactical sugar.
=> Int
和 () => Int
不是一个意思。一个是计算结果为 Int
的任何值,另一个是从 Unit
到 Int
的函数。 2
不是 () => Int
,但 () => 2
是。或者你也可以说 2
是 => Int
.
Why in this version we can't make addition of integer with value 2 and the param function (I mean thislazyEval(param _ + 2))? And what mean underscore after method name? (I guess it used to pass method itself, not it return value)
param
是方法,不是函数。本例中的下划线将 param
提升为一个函数。所以 param _
是一个函数 () => Int
。这正是我们不能将 2
添加到它的原因,因为您不能将 2
添加到函数。基本上就是您认为 (1) 不可行的确切原因。
总结:
def lazyEval(x: => Int)
是一个带有参数 x
的方法,它可以是 任何计算结果为 Int
的东西。这可以是 returns Int
的任何方法,Int
的具体值,或者解析为 Int
的某个代码块,等等
lazyEval(x: () => Int)
是一个有参数x
的方法,它只能是returnsInt
的无参数函数。这可能意味着方法 param
被提升为一个函数,或者像 () => 2
这样奇怪的东西。但它必须是一个函数。所以简单地传递一个像 2
这样的值是行不通的。
正如@m-z 指出的那样,value: => T
可以被认为是一个 语法 用于创建一个 方法 包装一个给定的表达式:
object Magician {
def magic(param: => Int) = param
}
object App {
val result: Int = Magician.magic(3 + 3)
}
翻译(大致)为:
object App {
private[this] def magic$param: Int = 3 + 3
val result: Int = Magician.magic(magic$param _)
}
按名称调用参数的 行为 类似于无参数方法定义 - 引用任一方法都会导致调用该方法:
def paramlessMethod = 3 + 3
def callByName(param: => Int) = param + paramlessMethod
def test() = callByName(5 + 5) // 16, always
在这两种情况下,您都可以 "lift" 通过使用魔术 _
Function0
(或者 "defer the evaluation of the method",如果您更愿意这样想的话)的方法]:
def paramlessMethod = 3 + 3
val functionWrapper: Function0[Int] = paramlessMethod _
functionWrapper() // 6
def callByName(param: => Int) = param _
val functionFromParam: Function0[Int] = callByName(3 + 3)
functionFromParam() // 6
这里解释def i: Int
的类型:
http://www.scala-lang.org/files/archive/spec/2.11/03-types.html#method-types
别名参数的类型i: => Int
解释如下:
The type of such a parameter is then the parameterless method type =>
T.
也就是说和方法类型一样def i: Int
.
我对在 Scala 中使用按名称调用参数有点困惑。请帮助我了解这里发生了什么。考虑以下使用按名称调用参数的示例:
def param = {println("Param evaluates"); 40}
def lazyEval(x: => Int) = {
println("lazy");
x
}
val s = lazyEval(param + 2)
// s = 42
关于这个我有几个相互关联的问题:
lazyEval
方法需要=> Int
类型的参数,那么为什么param + 2
操作是合法的呢?为什么我们可以在调用lazyEval
方法时将整数 2 添加到类型为=> Int
的对象(我的理解是<function0>
)?正如 IDE 提示我的那样,lazyEval
函数需要Int
类型的参数而不是=> Int
(到底是什么?)。为什么将回调类型从
=> Int
更改为() => Int
代码无法编译?这两种类型不同吗?我虽然简短的版本 ('=> Int') 只是一个语法糖。在尝试了一些代码之后,我终于可以更改代码以便它可以使用
() => Int
进行编译。这种方式对我来说更直观。
.
def param = {println("Param evaluates"); 40}
def lazyEval(x: () => Int) = { // changed type to '() => Int'
println("lazy");
x() // explicitly calling function using parentheses '()'
}
val s = lazyEval(param _) // adding underscore after method name and removing `+2`
这个版本和第一个版本(回调 => Int
类型)有什么区别?为什么在这个版本中我们不能将值为 2
的整数和 param
函数相加(我的意思是这个 lazyEval(param _ + 2)
)?方法名称后的下划线是什么意思? (我猜它曾经传递方法本身,而不是 return 值)
感谢帮助
so why param + 2 operation is legal? Why we can add integer 2 to object with type => Int
我们可以将 2
添加到 param
,因为它的计算结果是 Int
,您正在添加 Int
和 Int
。 param
不是一个函数 => Int
,它是一个方法,所以 param + 2
是 => Int
。 IE。计算结果为 Int
.
Why after changing callback type from => Int to () => Intcode doesn't compile? Is this 2 types are different? I though the short version ('=> Int') is just a syntactical sugar.
=> Int
和 () => Int
不是一个意思。一个是计算结果为 Int
的任何值,另一个是从 Unit
到 Int
的函数。 2
不是 () => Int
,但 () => 2
是。或者你也可以说 2
是 => Int
.
Why in this version we can't make addition of integer with value 2 and the param function (I mean thislazyEval(param _ + 2))? And what mean underscore after method name? (I guess it used to pass method itself, not it return value)
param
是方法,不是函数。本例中的下划线将 param
提升为一个函数。所以 param _
是一个函数 () => Int
。这正是我们不能将 2
添加到它的原因,因为您不能将 2
添加到函数。基本上就是您认为 (1) 不可行的确切原因。
总结:
def lazyEval(x: => Int)
是一个带有参数 x
的方法,它可以是 任何计算结果为 Int
的东西。这可以是 returns Int
的任何方法,Int
的具体值,或者解析为 Int
的某个代码块,等等
lazyEval(x: () => Int)
是一个有参数x
的方法,它只能是returnsInt
的无参数函数。这可能意味着方法 param
被提升为一个函数,或者像 () => 2
这样奇怪的东西。但它必须是一个函数。所以简单地传递一个像 2
这样的值是行不通的。
正如@m-z 指出的那样,value: => T
可以被认为是一个 语法 用于创建一个 方法 包装一个给定的表达式:
object Magician {
def magic(param: => Int) = param
}
object App {
val result: Int = Magician.magic(3 + 3)
}
翻译(大致)为:
object App {
private[this] def magic$param: Int = 3 + 3
val result: Int = Magician.magic(magic$param _)
}
按名称调用参数的 行为 类似于无参数方法定义 - 引用任一方法都会导致调用该方法:
def paramlessMethod = 3 + 3
def callByName(param: => Int) = param + paramlessMethod
def test() = callByName(5 + 5) // 16, always
在这两种情况下,您都可以 "lift" 通过使用魔术 _
Function0
(或者 "defer the evaluation of the method",如果您更愿意这样想的话)的方法]:
def paramlessMethod = 3 + 3
val functionWrapper: Function0[Int] = paramlessMethod _
functionWrapper() // 6
def callByName(param: => Int) = param _
val functionFromParam: Function0[Int] = callByName(3 + 3)
functionFromParam() // 6
这里解释def i: Int
的类型:
http://www.scala-lang.org/files/archive/spec/2.11/03-types.html#method-types
别名参数的类型i: => Int
解释如下:
The type of such a parameter is then the parameterless method type => T.
也就是说和方法类型一样def i: Int
.