2012-11-02 16 views
10

Scala'da oldukça yeniyim ve özelliklerden gelen verileri korurken bir vaka sınıfını kopyalamanın en iyi yolu hakkında bir sorum var.Scala: Vaka sınıflarını özelliklerle kopyalama

trait Auditing { 

    var createTime: Timestamp = new Timestamp(System.currentTimeMillis) 
} 

case class User(val userName: String, val email: String) extends Auditing 

val user = User("Joe", "[email protected]") 

Sonra tek bir parametre ile yeni bir kopyasını değişti yapmak istiyorum: Örneğin, aşağıdaki ı olduğunu varsayalım

val user2 = user.copy(email = "[email protected]") 

Şimdi, yukarıdaki örnekte, mülkiyet createTime almaz User case sınıfının kurucusunda tanımlanmadığı için kopyalandı. Yani sorum şu: kurucuya hareketli createTime'ın bir seçenek olmadığını varsayarak, özellikten gelen değeri içeren Kullanıcı nesnesinin bir kopyasını almanın en iyi yolu nedir? Ben

Şimdiden teşekkürler Scala 2.9.1

kullanıyorum

! Joe

+0

önünüzde çok seçenek vardır değil: manuel 'User' vaka sınıfının bildiriminde istediğiniz kopyayı üretecek böyle bir yöntemi uygulamak ya da 2.10 makro o otomatikleştirmek özelliğini Scala kullanın ya. İkinci seçenek kesinlikle yeni başlayanlar için kolay bir iş olmayacaktır. –

+1

@NikitaVolkov Bana/bize makrolarla nasıl yapılacağına dair bir örnek vermeye istekli olsaydınız, bu harika olurdu. –

+2

@mhs Kulübüne katıldım. Makrolarda yeni bir arıyım, bu yüzden cevap olarak göndermedim. Ama [işte nasıl] (http://stackoverflow.com/a/10397595/485115) 'Toolbox' api ile çok benzer bir görevi çözdüm. Kabul edilen cevap makrolara dayanıyor, ancak en son Scala sürümünü desteklemiyor. –

cevap

6

Kopyalama yöntemini bu davranışla geçersiz kılabilirsiniz. Reuben en dışında başka bir çözüm görürken

case class User(val userName: String, val email: String) extends Auditing 
{ 
    def copy(userName = this.userName, email = this.email) { 
    val copiedUser = User(userName, email) 
    copiedUser.createTime = createTime 
    copiedUser  
    } 
} 
3

, ben bakir yapıcı args bırakmak şartı anlamıyorum. Eğer gereken

case class User private (userName: String, email: String, 
    override val createTime:Timestamp) extends Auditing { 
    def this(userName: String, email: String) = 
    this(userName, email, new Timestamp(System.currentTimeMillis)) 
} 

tek dezavantajı şudur: kullanıcı createTime üzerine yazmak mümkün istemiyorsanız

case class User(userName: String, email: String, 
    override val createTime:Timestamp = new Timestamp(System.currentTimeMillis)) 
     extends Auditing 

, hala kullanabilirsiniz: Bu en doğal çözüm olacaktır birincil kurucu artık özel olduğundan new User("Joe", "[email protected]") yazınız.

0

Bir vaka sınıfı kullanmamanız daha iyi olabilir. İhtiyacınız olan işlevselliğini kolayca uygulayabilirsiniz. Aşağıdaki kod, istediğiniz kopya yöntemini uygular, yeni yapıcı olmayan bir kurucu, orijinal kurucuyu gizler ve bir ekstraktör oluşturur.

class User private(val userName: String, 
        val email: String, 
        val timeStamp: Timestamp = 
        new Timestamp(System.currentTimeMillis)) { 

    def copy(uName: String = userName, 
      eMail: String = email) = 
    new User(uName, eMail, timeStamp) 
} 

object User { 
    def apply(userName: String, email: String) = 
    new User(userName, email) 

    def unapply(u: User) = Some((u.userName, u.email, u.timeStamp)) 
} 
İlgili konular