You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala 3与Scala 2.13同名内部trait混入差异问题咨询

Scala 3中同名内部Trait混入的兼容性变更问题

问题复现

以下代码在Scala 2.13可正常编译:

trait First {
    val first: Service

    trait Service {
        def someMethod(): Int
    }
}

trait LiveFirst extends First {
    override val first: Service = new Service {
        override def someMethod(): Int = 1
    }
}

trait Second {
    val second: Service

    trait Service {
        def someMethod(): Int
    }
}

trait LiveSecond extends Second {
    override val second: Service = new Service {
        override def someMethod(): Int = 2
    }
}

type Mixed = First with Second
val mixed: Mixed = new LiveFirst with LiveSecond

但在Scala 3编译时会抛出错误:

[error] 32 |val mixed: Mixed = new LiveFirst with LiveSecond
[error]    |                   ^
[error]    |error overriding trait Service in trait First;
[error]    |  trait Service in trait Second cannot be used here - class definitions cannot be overridden

Scala 3的具体变更

Scala 2中,编译器会将不同父特质内的同名内部特质视为独立符号,混入时不会触发冲突检查。但Scala 3对嵌套类型的继承解析规则做了严格化调整:

当多个包含同名内部特质的父特质被混入到同一个类/实例中时,Scala 3会将这些内部特质解析为当前实例下的嵌套成员,认为Second.Service试图覆盖First.Service的定义。而Scala 3明确禁止类或特质定义被覆盖,因此抛出上述错误。

简单来说,Scala 3不再允许同一个类作用域中存在同名的嵌套特质/类定义,即使它们来自不同的父特质。

修复方案

可以通过明确指定路径依赖类型来区分不同的内部特质,避免编译器将它们视为同一成员:

修改LiveFirst和LiveSecond的实现,显式使用父特质的路径限定内部特质:

trait LiveFirst extends First {
    override val first: First.Service = new First.Service {
        override def someMethod(): Int = 1
    }
}

trait LiveSecond extends Second {
    override val second: Second.Service = new Second.Service {
        override def someMethod(): Int = 2
    }
}

也可以直接修改其中一个内部特质的名称,从根源避免同名冲突。

内容的提问来源于stack exchange,提问作者Pavel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 10:31:11