Scala:尝试了扩展方法,但无法完全构造(多个类上的扩展名相同)

Posted

技术标签:

【中文标题】Scala:尝试了扩展方法,但无法完全构造(多个类上的扩展名相同)【英文标题】:Scala: An extension method was tried, but could not be fully constructed (same extension name on multiple classes) 【发布时间】:2022-01-16 08:13:06 【问题描述】:

在 Scala 中,我试图在两个不同的类上定义扩展方法。我希望两个类的扩展方法具有相同的名称。

请注意,这些类与继承无关。

例如,假设我有两个 case classes AB,每个都有一个 String 属性,我想在这两个类上定义一个 lower 方法,它将返回小写他们的财产:

import SomeObject.AExt.lower
import SomeObject.BExt.lower

object SomeObject 

  case class A(foo: String)

  case class B(bar: String)

  object AExt 
    extension (x: A) def lower = x.foo.toLowerCase
  

  object BExt 
    extension (x: B) def lower = x.bar.toLowerCase
  

  def hello(): Unit = 
    def a = A("foo")

    def b = B("bar")

    println(a.lower)
    println(b.lower)
  

编译失败并出现以下错误:

An extension method was tried, but could not be fully constructed:

    SomeObject.BExt.lower(a)    failed with

        Found:    SomeObject.A
        Required: SomeObject.B

看起来编译器很困惑,并试图将类 B 上定义的 lower 扩展应用到我的 A 实例。

【问题讨论】:

【参考方案1】:

一种解决方法是将扩展方法放在同一个对象中:

import SomeObject.ABExt.lower
object SomeObject 

  case class A(foo: String)

  case class B(bar: String)

  object ABExt 
    extension (x: A) def lower = x.foo.toLowerCase
    extension (x: B) def lower = x.bar.toLowerCase
  

  def hello(): Unit = 
    def a = A("foo")

    def b = B("bar")

    println(a.lower)
    println(b.lower)
  

【讨论】:

以上是关于Scala:尝试了扩展方法,但无法完全构造(多个类上的扩展名相同)的主要内容,如果未能解决你的问题,请参考以下文章

Scala案例类私有构造函数但公共应用方法

Scala中 object 和 class的区别

《快学Scala》第八章——继承

Scala:如何在case类构造函数中使用类型作为第一类值?

如果我在 Scala 中定义多个重载构造函数,我不能定义默认值吗?

如何创建类型化工厂方法构造函数的类层次结构并使用抽象类型从 Scala 访问它们?