gpt4 book ai didi

scala - 隐式类应该总是扩展 AnyVal 吗?

转载 作者:行者123 更新时间:2023-12-02 01:49:38 26 4
gpt4 key购买 nike

假设我正在编写一个扩展方法

implicit class EnhancedFoo(foo: Foo) {
def bar() { /* ... */ }
}

您是否应该始终在类定义中包含extends AnyVal?在什么情况下您不想将隐式类设为值类?

最佳答案

让我们看看 limitations listed for value classes并思考它们何时可能不适合隐式类:

  1. “必须只有一个主构造函数,并且具有一个公共(public) val 参数,其类型不是值类。”因此,如果您要包装的类本身就是一个值类,则您不能使用隐式类作为包装器,但您可以这样做:

    // wrapped class
    class Meters(val value: Int) extends AnyVal { ... }

    // wrapper
    class RichMeters(val value: Int) extends AnyVal { ... }

    object RichMeters {
    implicit def wrap(m: Meter) = new RichMeter(m.value)
    }

    如果您的包装器也有隐式参数,您可以尝试将它们移至方法声明中。 IE。而不是

    implicit class RichFoo[T](foo: Foo[T])(implicit ord: Ordering[T]) {
    def bar(otherFoo: Foo[T]) = // something using ord
    }

    你有

    implicit class RichFoo[T](foo: Foo[T]) extends AnyVal {
    def bar(otherFoo: Foo[T])(implicit ord: Ordering[T]) = // something using ord
    }
  2. “可能没有专门的类型参数。”在包装本身具有专门类型参数的类时,您可能希望包装器是专门的。

  3. “可能没有嵌套或本地类、特征或对象”,这对于实现包装器可能很有用。
  4. “不得定义 equalshashCode 方法。”无关紧要,因为隐式类也不应该具有 equals/hashCode
  5. “必须是顶级类或静态可访问对象的成员”这也是您通常定义隐式类的位置,但不是必需的。
  6. “只能将 def 作为成员。特别是,它不能将惰性 val、var 或 val 作为成员。”隐式类可以拥有所有这些,尽管我无法想到 varlazy val 的合理用例。
  7. “不能由另一个类扩展。”同样,隐式类可以扩展,但可能没有充分的理由。

此外,使隐式类成为值类可能会更改使用反射的代码的某些行为,但反射通常不应看到隐式类。

如果您的隐式类确实满足所有这些限制,我想不出不将其设为值类的理由。

关于scala - 隐式类应该总是扩展 AnyVal 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14929422/

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