gpt4 book ai didi

scala - 如何在编译时进行类型检查?

转载 作者:行者123 更新时间:2023-12-04 22:37:01 25 4
gpt4 key购买 nike

TraversableOnce 中,有一个 sum 方法,只有在包含的类型是 Numeric 时才可用(否则它不会编译)。我想知道这是否可用于其他情况(以避免运行时检查)。

特别是我们有两个特征 A 和 B 的情况。我们希望有一个方法 f ,只有当对象继承 A 和 B 时才能使用它。但如果它只扩展其中一个,则不能使用。我不想制作另一个 trait AB extends A with B 。如果不是两个特征都被继承,我只是想无法使用 f

package com.example

trait Base
trait Foo extends Base {
def g = println("foo bar " + toString)
}
trait Bar extends Base {
/* If this is both Foo and Bar, I can do more */
def f = {
if (!this.isInstanceOf[Foo]) error("this is not an instance of Foo")
this.asInstanceOf[Foo].g
}
}
object Test {
def main(args: Array[String]): Unit = {
object ab extends Foo with Bar
object ba extends Bar with Foo
object b extends Bar
ab.f
ba.f
// I don't want next line to compile:
try { b.f } catch { case e: RuntimeException => println(e) }
}
}

编辑:解决方案,感谢@Aaron Novstrup
trait Bar extends Base { self =>
def f(implicit ev: self.type <:< Foo) = {
//self.asInstanceOf[Foo].g // [1]
ev(this).g // [2]
}
}

现在在 main 中, b.f 无法编译。好的

编辑 2:将第 [1] 行更改为 [2] 反射(reflect)@Aaron Novstrup 的答案变化

编辑 3:不使用 self 反射(reflect)@Aaron Novstrup 回答的变化
trait Bar extends Base {
/* If this is both Foo and Bar, I can do more */
def f(implicit ev: this.type <:< Foo) = {
ev(this).g
}
}

最佳答案

是的你可以:

trait A {
def bar = println("I'm an A!")
}

trait B {
def foo(implicit ev: this.type <:< A) = {
ev(this).bar
println("and a B!")
}
}

如果对象的静态类型(在调用点)扩展 evidence ,编译器将只能提供 A 参数。

关于scala - 如何在编译时进行类型检查?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4404407/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com