2013-08-30 55 views
1

我无法找到一个自然的方式做这样的事情,在斯卡拉:末多初始化

class Car { 
    var speed: Int 
    var color: String 
} 

var myCar = new Car() 

myCar.set { 
    speed = 5 
    color = "green" 
} 

我知道这是可能在其他语言比如Groovy。我也知道我可以用这样的构造做:

val myCar = new Car { 
    speed = 5 
    color = "green" 
} 

我感兴趣的方式做同样的,而不是在对象的构造,但后来,一旦对象已经创建

这是我到目前为止已经做的:

class Car (var speed: Int, var color: String) { 

    def set(f: (Car) => Unit) = { 
    f(this) 
    } 

} 

val myCar = new Car(5, "red") 
myCar.set { c => 
    c.speed = 12 
    c.color = "green" 
} 

但我不喜欢,需要写的“C”变种每个属性

我如何能做到这一点,或者如果疗法任何想法e是一种更简单的方法?

回答

2

除非绝对必要,否则应该避免可变类。如果你想坚持的可变类型,为什么

case class Car(speed: Int, color: String) 

val c1 = Car(5, "red") 
val c2 = c1.copy(speed = 12, color = "green") 

(然后c2是汽车的一个新版本,而c1保持不变。)


:你会在斯卡拉通常这做不只是

class Car(var speed: Int, var color: String) 

val myCar = new Car(5, "red") 
import myCar._ 
speed = 12 
color = "green" 

用专用set方法去:

class Car(var speed: Int, var color: String) { 
    def set(speed: Int = this.speed, color: String = this.color): Unit = { 
    this.speed = speed 
    this.color = color 
    } 
} 

val myCar = new Car(5, "red") 
myCar.set(speed = 12, color = "green") 
myCar.set(color = "blue") 
+0

在我的方面,我有对象池我重用。我不创建新的对象,因为它的实现速度很慢,这就是为什么我有一个可变类。 我发现第二个版本不是很容易阅读,即使它基本上是我想要做的 – itsu

+0

然后看到我的第三个版本 –

+0

好吧,对不起,我没有解释真的解释我的整个想法... 随着第三个版本,你在更新类属性时总是需要更新函数。另外你也不能调用任何方法。 我真正想要做的是既 myCar.set { 速度= 12 颜色=“绿色” 移动() 停止() } 这就是为什么我需要更多的东西一般 – itsu

1

虽然大家都同意说VAR reassignement是丑陋的,这是一个可能的解决方案

object DoTo { 
    def apply[T](that: T)(functions: (T) => Unit*): T = { 
    functions foreach { _.apply(that) } 
    that 
    }  
} 


class Car (var speed: Int, var color: String) { 
    def move() = println("moving") 
    def stop() = println("stop") 
} 


val myNewCar = DoTo(new Car(12, "red")) (
    _.move(), 
    _.stop(), 
    _.speed = 15, 
    _.color = "green" 
) 

这不正是我想要的最初,但我无法找到任何简单利用内部消除宏:-(

1

您可以通过导入一个变量做到这一点:

class Car { 
    var speed: Int = _ 
    var color: String = _ 
} 

// ... 
val myCar = new Car(); 
// a blocks that works with myCar: 
{ 
    import myCar._ 
    // access the content without any prefix 
    speed = 5 
    color = "green" 
}