[英]Scala Thunk or Code Block
我在SCALA GOTCHA中阅读了有关棘手的Scala代码块的内容:块和功能以及Alvin的博客。 这是Alvin的示例的后续操作,在该示例中,他使用泛型函数f: A=> B
作为代码块参数,而不是() => A
或=> A
我更改了代码以返回Int
而不是String
,请参阅#1
,
case class Foo[A, B](f: A => B) {
println(f)
def print1 { println("1") }
}
object AnonymousClassTest1 extends App {
val f1 = Foo {
println("hello from the `f1` instance")
// "this is the result of the block of code" // #1
123
}
f1.print1
}
这段代码编译有错误,
Example.scala:5: error: type mismatch;
found : Int(123)
required: ? => ?
123
^
one error found
鉴于f是一个通用函数,它接受任何东西并返回任何东西。 为什么会出现编译错误? 为什么它可以接受String但不能接受Int? 谢谢。
让我们将解释分为两部分:Scala允许替换参数列表,该参数列表恰好接受block的一个参数:
def foo(arg: Int) = arg + 42
foo(42) == foo { 42 }
因此,对于您的代码,以下内容应为真
val f1 = Foo {
myGreatCode
}
val f2 = Foo(myGreateCode)
f1 == f2
从块中“返回”的值(表示类型)是后者中的最后一个表达式,因此在您的情况下:
val f1 = Foo {
println("hello from the `f1` instance")
// "this is the result of the block of code" // #1
123
}
f1 == Foo(123) // println is executed before creating Foo
我希望它能解释您为什么会出现编译错误。 为了满足您的需求,scala提供了特殊的语法,允许在块中定义函数:
val f2 = Foo { x: String =>
x.toInt
} // Foo[String, Int]
编辑:
经过评论中的讨论,我发现解释了Foo("123")
为何编译。 如果有人检查了代码,他/她将发现以下实例的通用参数为: Foo[Int, Char]
。 发生这种情况是由于以下原因:
编译器期望Foo.apply的参数是一个函数
传递的值不是函数,因此编译器会寻求隐式转换为1。
它发现: implicit def wrapString(s: String): WrappedString = if (s ne null) new WrappedString(s) else null
并且WrappedString
扩展IndexedSeq[Char]
,这又扩展了Int => Char
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.