我试图为我的User类层次结构编写一些通用构建器。 我有一个特点,UserBuilder和每个"与"特征中的方法必须返回与当前类相同的类型。因此,如果我在ComplexUserBuilder中,则withId方法应返回ComplexUserBuilder,而不是UserBuilder。
但是我得到了
涉及类型T的非法循环引用
有没有办法解决这个问题?
这是我的代码:
trait UserBuilder[T >: UserBuilder[T]] {
var id: String = ""
def withId(id: String): T = {
this.id = id
return this
}
}
class ComplexUserBuilder extends UserBuilder[ComplexUserBuilder] {
var username: String = ""
def withUsername(username: String): ComplexUserBuilder = {
this.username = username
return this
}
def build = new ComplexUser(id, username)
}
顺便说一句,如果我将trait UserBuilder[T >: UserBuilder[T]]
替换为trait UserBuilder[T >: UserBuilder[_]]
,我会得到:
类型参数[model.ComplexUserBuilder]不符合特征UserBuilder的类型参数边界[T>:model.UserBuilder [_]]
更新
trait UserBuilder[T >: UserBuilder[T]]
应该是(如GClaramunt建议的那样)
trait UserBuilder[T <: UserBuilder[T]]
但现在有一个丑陋的演员作为返回类型
答案 0 :(得分:4)
要使UserBuilder
子类具有对自己类型的引用,您应该声明this
的类型(并使它们 sub -types,而不是超级 -types,UserBuilder
):
trait UserBuilder[T <: UserBuilder[T]] { this: T =>
...
}
答案 1 :(得分:4)
trait UserBuilder {
var id: String = ""
def withId(id: String): this.type = {
this.id = id
return this
}
}
class ComplexUserBuilder extends UserBuilder {
var username: String = ""
def withUsername(username: String): this.type = {
this.username = username
return this
}
def build = new ComplexUser(id, username)
}
并且,如果要将构建方法添加到UserBuilder特征,您可能需要添加泛型类型U来约束用户类型,例如
trait UserBuilder[U <: { def id: String }] {
var id: String = ""
def withId(id: String): this.type = {
this.id = id
return this
}
def build: U
}
class ComplexUserBuilder extends UserBuilder[ComplexUser] {
var username: String = ""
def withUsername(username: String): this.type = {
this.username = username
return this
}
def build = new ComplexUser(id, username)
}
答案 2 :(得分:1)
我不确定你想要达到的是什么,但你有向后的上限类型限制应该是&#34;&lt;:&#34;而不是&#34;:&gt;&#34;
产品:&gt;是一个较低类型的绑定限制,意思是,T必须是UserBuilder的超类型,你想要一个子类型(所以你可以扩展UserBuilder)
trait UserBuilder[T <: UserBuilder[T]] {
self: T =>
var id: String = ""
def withId(id: String): T = {
this.id = id
this
}
}
class ComplexUserBuilder extends UserBuilder[ComplexUserBuilder] {
var username: String = ""
def withUsername(username: String): ComplexUserBuilder = {
this.username = username
this
}
//def build = new ComplexUser(id, username)
}
此外,您不需要&#34;返回&#34;,(几乎)Scala中的所有内容都是一个返回值的表达式。