gpt4 book ai didi

scala - 使用扩展方法规避差异检查

转载 作者:行者123 更新时间:2023-12-04 18:55:46 25 4
gpt4 key购买 nike

这不编译:

class MyClass[+A] {
def myMethod(a: A): A = a
}
//error: covariant type A occurs in contravariant position in type A of value a

好吧,够公平的。但这确实编译:
class MyClass[+A]

implicit class MyImplicitClass[A](mc: MyClass[A]) {
def myMethod(a: A): A = a
}

这让我们可以规避方差检查给我们带来的任何问题:
class MyClass[+A] {
def myMethod[B >: A](b: B): B = b //B >: A => B
}

implicit class MyImplicitClass[A](mc: MyClass[A]) {
def myExtensionMethod(a: A): A = mc.myMethod(a) //A => A!!
}

val foo = new MyClass[String]
//foo: MyClass[String] = MyClass@4c273e6c

foo.myExtensionMethod("Welp.")
//res0: String = Welp.

foo.myExtensionMethod(new Object())
//error: type mismatch

这感觉像是在作弊。应该避免吗?或者编译器让它滑动有什么正当理由吗?

更新:

考虑一下这个例子:
class CovariantSet[+A] {
private def contains_[B >: A](b: B): Boolean = ???
}

object CovariantSet {
implicit class ImpCovSet[A](cs: CovariantSet[A]) {
def contains(a: A): Boolean = cs.contains_(a)
}
}

看来我们已经设法实现了不可能的目标:仍然满足 A => Boolean 的协变“集合”。 .但如果这是不可能的,编译器不应该禁止它吗?

最佳答案

我不认为它比脱糖后的版本更作弊:

val foo: MyClass[String] = ...
new MyImplicitClass(foo).myExtensionMethod("Welp.") // compiles
new MyImplicitClass(foo).myExtensionMethod(new Object()) // doesn't

原因是 MyImplicitClass 上的类型参数在 myExtensionMethod 之前推断构造函数被认为。

最初我想说它不会让你“规避 任何 方差检查给我们带来的问题”,因为扩展方法需要用方差合法方法来表达,但这是错误的:它可以在伴生对象中定义并使用私有(private)状态。

我看到的唯一问题是修改代码的人可能会感到困惑(甚至不阅读它,因为那些人​​不会看到非编译代码)。我不认为这会是一个大问题,但是如果没有在实践中尝试,很难确定。

关于scala - 使用扩展方法规避差异检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55455707/

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