实现支持方法链的 Scala 特征的最佳实践

发布于 2024-10-14 17:36:18 字数 685 浏览 3 评论 0原文

我想创建一个特征,向类添加一些属性并使链接方法成为可能。在 Scala 2.8.1 中测试。

trait SomeProperty {
    var prop : String = "default"
    def setProp(s: String) = {
        prop = s
        this
    }
}
sealed abstract class Value
case class IntegerValue(v: Int) extends Value
case class FloatValue(v: Float) extends Value with SomeProperty {
    def foo() = { println("I'm foo.") }
}
case object UnknownValue extends Value with SomeProperty {
    def bar() = { println("I'm bar.") }
}

scala> val x = UnknownValue
scala> x.setProp("test").bar()
<console>:10: error: value bar is not a member of SomeProperty
   x.setProp("test").bar()

在这种情况下最常见的做法是什么? (首选类型安全的方式)

I want to make a trait which add some property to a class and make it possible to chain methods. Tested in Scala 2.8.1.

trait SomeProperty {
    var prop : String = "default"
    def setProp(s: String) = {
        prop = s
        this
    }
}
sealed abstract class Value
case class IntegerValue(v: Int) extends Value
case class FloatValue(v: Float) extends Value with SomeProperty {
    def foo() = { println("I'm foo.") }
}
case object UnknownValue extends Value with SomeProperty {
    def bar() = { println("I'm bar.") }
}

scala> val x = UnknownValue
scala> x.setProp("test").bar()
<console>:10: error: value bar is not a member of SomeProperty
   x.setProp("test").bar()

What is the most common practice in this kind of situation? (Type-safe way is preferred)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

远昼 2024-10-21 17:36:18

您可以显式指定实例类型作为 setProp 的返回类型。

trait SomeProperty {
    var prop : String = "default"
    def setProp(s: String):this.type = {
        prop = s
        this
    }
}

You can explicitly specify the instance type as the return type for setProp.

trait SomeProperty {
    var prop : String = "default"
    def setProp(s: String):this.type = {
        prop = s
        this
    }
}
荒人说梦 2024-10-21 17:36:18

不确定这是否是您要找的

scala> trait Property[T] {
     |   me: T =>
     |   var prop:String=""
     |   def setProp(s:String) = {
     |     prop=s
     |     me
     |   }
     | }
defined trait Property

scala> class A extends Property[A]
defined class A

scala> class B extends Property[B]
defined class B

scala> val a= new A
a: A = A@694a18

scala> val b = new B
b: B = B@1108691

scala> a.setProp("Hi")
res13: Property[A] with A = A@694a18

scala> a.setProp("Hi").setProp("Bye")
res14: Property[A] with A = A@694a18

scala> b.setProp("D")
res15: Property[B] with B = B@1108691

Not sure if this is what you're looking for

scala> trait Property[T] {
     |   me: T =>
     |   var prop:String=""
     |   def setProp(s:String) = {
     |     prop=s
     |     me
     |   }
     | }
defined trait Property

scala> class A extends Property[A]
defined class A

scala> class B extends Property[B]
defined class B

scala> val a= new A
a: A = A@694a18

scala> val b = new B
b: B = B@1108691

scala> a.setProp("Hi")
res13: Property[A] with A = A@694a18

scala> a.setProp("Hi").setProp("Bye")
res14: Property[A] with A = A@694a18

scala> b.setProp("D")
res15: Property[B] with B = B@1108691
杀お生予夺 2024-10-21 17:36:18

最简单的事情就是使用泛型。

object Value {

  trait SomeProperty[X] {
    var str: String = null;
    def setStr(s: String): X = {
      str = s;
      return this.asInstanceOf[X]
    }
  }

  abstract sealed class Value
  case class IntegerValue(i: Int)
  case class StringValue(s: String) extends SomeProperty[StringValue] {
    def foo(): Unit = {
      println("Foo.")
    }
  }
  case class UnknownValue(o: Any) extends SomeProperty[UnknownValue] {
    def bar(): Unit = {
      println("Bar.")
    }
  }

  def main(args: Array[String]): Unit = {

    new UnknownValue(18).setStr("blah blah blah").bar
    new StringValue("A").setStr("halb halb halb").foo
  }
}

Easiest thing to do is use a generic.

object Value {

  trait SomeProperty[X] {
    var str: String = null;
    def setStr(s: String): X = {
      str = s;
      return this.asInstanceOf[X]
    }
  }

  abstract sealed class Value
  case class IntegerValue(i: Int)
  case class StringValue(s: String) extends SomeProperty[StringValue] {
    def foo(): Unit = {
      println("Foo.")
    }
  }
  case class UnknownValue(o: Any) extends SomeProperty[UnknownValue] {
    def bar(): Unit = {
      println("Bar.")
    }
  }

  def main(args: Array[String]): Unit = {

    new UnknownValue(18).setStr("blah blah blah").bar
    new StringValue("A").setStr("halb halb halb").foo
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文