gpt4 book ai didi

scala - 不可变的类和特征?

转载 作者:行者123 更新时间:2023-12-04 12:41:39 25 4
gpt4 key购买 nike

在学习使用 Scala 中的不可变主体时,我似乎遇到了很多问题,其中之一是从相关对象中克隆(或者更确切地说是派生)的概念。

这些问题之一是混合特征的概念 - 示例

trait helper //modifies some kind behavior.. assume we want to to continue down the line

class A (val x:int) {

def add(y:int) = new A(x + y)
}

Example extends App {

val a =new A(5) with helper
val b = a.add(10) // mixed trait disappears

}

现在这只是我今天围绕各种类构建的更复杂问题的一个非常简单的版本,隐藏类 A 的工厂方法等。如果我们只处理一个特征,我知道我可以简单地测试它并且根据需要转发。但是如果可能存在超过 3 个或更多的特征,我该怎么办?我将不得不测试所有不切实际的组合。

您如何在遵守功能设计原​​则的同时实例化(克隆)具有各种特征的现有对象和/或修改它的某些方面?

非常感谢,
- 蒂姆

最佳答案

Collections 使用隐式构建器,它知道如何从您开始的内容中生成您的目标类型。这两种类型并不总是一回事。

有很多关于类型安全构建器的相关帖子,它们控制可以生成的内容,例如,
http://nullary.blogspot.com/2011/10/builder-pattern-revisited-in-scala.html

一个相关的问题是如果你有一个混合类型的集合怎么办:
Polymorphic updates in an immutable class hierarchy

在值轴上,跟踪值而不是编码类型
What is the Scala equivalent to a Java builder pattern?

更新:在游戏时间出现了类似的情况。在 ML 和 here 中描述了在模式中使用 REs .

package object interpat {
implicit class MySContext (val sc : StringContext) {
object mys {
def apply (args : Any*) : String = sc.s (args : _*)
def unapplySeq (s : String) : Option[Seq[String]] = {
val regexp = sc.parts.mkString ("(.+)").r
regexp.unapplySeq (s)
}
}
}
implicit class SBContext (val sc : StringContext) {
def sb(args: Any*): SB = new SB(sc.s (args : _*))
}
implicit class toHasPattern(sb: SB) {
def /(pp: String) = new SB(sb.s) with HasPattern {
val p = pp
}
}
implicit class toHasRepl(hasp: SB with HasPattern) {
def /(rr: String) = new SB(hasp.s) with HasPattern with HasRepl with Updateable {
val p = hasp.p
val r = rr
}
}
// disallow it
implicit class noway(hasr: SB with HasPattern with HasRepl) {
def /(rr: String) = ???
}
implicit class noway2(hasr: SB with HasPattern with HasRepl) {
def /(rr: String) = ???
}
}

使用类型参数控制隐式的用法和替代方法。
package interpat {
import scala.util.Try
object I { def unapply(x: String): Option[Int] = Try(x.toInt).toOption }

trait XX {
type HasIt
type Yes <: HasIt
type No <: HasIt
}
object XX extends XX {
implicit class XContext (val sc : StringContext) {
def x(args: Any*) = new X[No, No] {
val s = sc.s(args : _*)
}
}
implicit class xPat(x: X[No, No]) {
def /(pp: String) = new X[Yes, No] with HasPattern {
val s = x.s
val p = pp
}
}
implicit class xRep(x: X[Yes, No] with HasPattern) {
def /(rr: String) = new X[Yes, Yes] with HasPattern with HasRepl {
val s = x.s
val p = x.p
val r = rr
override def toString = s replaceAll (p, r )
}
}
implicit class xable(xx: X[Yes, Yes]) {
def x = xx.toString
}
}
import XX._

trait X[HasP <: HasIt, HasR <: HasIt] {
def s: String
}

trait HasPattern {
def p: String
}

trait HasRepl {
def r: String
}

trait Updateable { this: HasPattern with HasRepl =>
def update(p: String, r: String)
override def toString = {
update(p, r)
super.toString
}
}

class SB(val s: String) {
final val sb = new StringBuilder(s)
def update(p: String, r: String): Unit =
sb.replace(0, sb.length, sb.toString.replaceAll(p, r))
override def toString = sb.toString
}

object Test extends App {
val msg = "The sky is blue" match {
case mys"The $thing is $colour" => mys"A $colour thing is $thing"
case _ => "no match"
}
println (msg)
val mys"The $thing is $colour" = "The sky is blue"
Console println s"$thing / $colour"
val mys"The ${I(number)} is blue" = "The 3 is blue"
Console println s"$number"
//sb"The sky is blue".update("blue","red")
// no way to get a value out!
sb"The sky is blue"("blue") = "red"
val ugh = sb"The sky is blue"
ugh("blue") = "red"
Console println ugh
val sx = sb"The sky is $colour" / "blue" / "red"
Console println sx
//sb"The sky is $colour" / "blue" / "red" / "yellow"
Console println sx
Console println x"The sky is $colour" / "blue" / "red"
Console println (x"The sky is $colour" / "blue" / "red").x
//Console println x"The sky is $colour" / "blue" / "red" / "yellow"
}
}

关于scala - 不可变的类和特征?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17265309/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com