繁体   English   中英

Scala Thunk或代码块

[英]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] 发生这种情况是由于以下原因:

  1. 编译器期望Foo.apply的参数是一个函数

  2. 传递的值不是函数,因此编译器会寻求隐式转换为1。

  3. 它发现: 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM