Scala中无法用SAM语法初始化Array?此行为是否符合预期?
这个行为完全符合预期,原因如下:
你遇到的类型不匹配错误,本质是因为**() => 5是一个函数类型() => Int,而你的Array[A]需要的是实现了trait A的实例**,这两者属于完全不同的类型范畴,Scala的强类型系统不会允许这种隐式转换。
先看你的trait A定义:它要求实现类必须提供一个num(): Int方法。而你写的() => 5只是一个无参返回Int的函数,它并没有实现A的num方法,也不是A的子类实例,所以编译器当然会报错。
修正后的正确写法
如果你想创建一个符合A类型的实例放进数组,需要显式实现trait A,比如用匿名类:
trait A { def num(): Int } trait B extends A trait C extends A // 用匿名类实现A的num方法 val nums: Array[A] = Array(new A { def num() = 5 })
或者你也可以定义一个具体的实现类来复用:
class ConcreteA(overrideVal num: Int) extends A { // 这里直接用参数实现num方法,简化代码 } val nums: Array[A] = Array(new ConcreteA(5))
额外说明
如果想要让函数可以被当作A的实例使用,你需要手动定义隐式转换,比如:
implicit def funcToA(f: () => Int): A = new A { def num() = f() } // 现在就可以直接把函数放进Array[A]了 val nums: Array[A] = Array(() => 5)
但这属于进阶用法,默认情况下Scala不会自动做这种转换,所以你最初遇到的错误是完全符合编译器预期的行为。
内容的提问来源于stack exchange,提问作者uh_big_mike_boi
相关产品推荐
相关产品推荐

