Scala Builder Pattern: Illegal loopback including type T

I am trying to write some general assemblies for my user class hierarchy. I have a trait, UserBuilder, and each method "c" in the attribute should return the same type as the current class. Therefore, if I'm inside ComplexUserBuilder, the withId method should return ComplexUserBuilder, not UserBuilder.

But I get

illegal circular reference including type T

Is there any way around this?

Here is my code:

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)
}

By the way, if I replace trait UserBuilder[T >: UserBuilder[T]]with trait UserBuilder[T >: UserBuilder[_]], I get:

arguments of type [model.ComplexUserBuilder] do not match the signs of user type restrictions UserBuilder [T>: model.UserBuilder [_]]

Update:

trait UserBuilder[T >: UserBuilder[T]]

should be (as suggested by GClaramunt)

trait UserBuilder[T <: UserBuilder[T]]

but now there is an ugly cast as return type

+4
3

UserBuilder , this ( , -, UserBuilder):

trait UserBuilder[T <: UserBuilder[T]] { this: T =>
  ...
}
+4

. , T, this.type scala.

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)
}
+4

, , "<:" ": > "

: > , 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)
  }

, "", () Scala - , .

+1
source

Source: https://habr.com/ru/post/1544238/


All Articles