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

Scala中Trait如何定义返回其子类型的方法?

问题描述

现有Scala trait及子类定义如下:

@ trait Foo {
    def withStuffAdded(str: String): Foo
  } 
defined trait Foo
@ class X(val str: String) extends Foo { 
    override def withStuffAdded(s: String): Foo = new X(str + s)
  } 
defined class X

尝试定义函数something时触发编译错误:

@ def something(x: X): X = x.withStuffAdded("something") 
cmd3.sc:1: type mismatch;
 found   : ammonite.$sess.cmd1.Foo
 required: ammonite.$sess.cmd2.X
def something(x: X): X = x.withStuffAdded("something")
                                         ^
Compilation Failed

报错原因是withStuffAdded声明返回Foo类型,但我们需要它返回调用者的实际子类型(如X),以满足函数something的返回值要求。

解决方案

使用**F-bounded多态(自类型参数)**修改Foo的定义,让trait能够引用自身的子类型,从而让withStuffAdded返回具体子类型:

修改后的Trait定义

@ trait Foo[Self <: Foo[Self]] {
    def withStuffAdded(str: String): Self
  }
defined trait Foo

调整子类X的实现

@ class X(val str: String) extends Foo[X] { 
    override def withStuffAdded(s: String): X = new X(str + s)
  }
defined class X

验证函数编译

此时重新定义something即可正常通过编译:

@ def something(x: X): X = x.withStuffAdded("something")
defined function something
原理说明
  • 给Foo添加自类型参数Self,并通过<: Foo[Self]限制该参数必须是Foo的子类,强制子类继承时传入自身作为类型参数。
  • 将withStuffAdded的返回类型改为Self,这样子类实现时可以返回自身类型,编译器能准确识别返回值的具体类型,消除类型不匹配的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 01:05:53