2015-08-29 33 views
0

我有一個case class User。我必須使用kryo序列化它。這是我的班。在scala中序列化時更改不可變的變量值

雖然執行Kryo read()我有問題。我的變量有val類型。因爲我們知道我們不能改變val的價值。

case class User(name : String, age : int) extends KryoSerializable { 

    def this()={ 
    this("",0) 
    } 

// 
override def read(kryo : Kryo, input : Input) { 
// here i'm getting error. i can't override name because its val 
name = input.readString() 
    age = input.readInt() 

    println("-----------Read method of Kryo") 

    } 

    override def write(kryo : Kryo, output : Output) { 
    output.writeString(name) 
    output.writeInt(age) 
    println("--------Write method of Kryo") 
    } 
} 

請指導我,我該怎麼做?

回答

1

如果您沒有任何緊迫的理由爲用戶使用case class,我建議不要使用case class。因爲你必須聲明姓名和年齡作爲變量。並且case class不是假定是可變的。

這是什麼東西,有可能做到,你想要什麼不做User一個case class

class User (private var _name : String, private var _age : Int) extends KryoSerializable { 

    def name = _name 
    def age = _age 

    override def read(kryo : Kryo, input : Input) { 
    // here i'm getting error. i can't override name because its val 
    _name = input.readString() 
    _age = input.readInt() 

    println("-----------Read method of Kryo") 

    } 

    override def write(kryo : Kryo, output : Output) { 
    output.writeString(_name) 
    output.writeInt(_age) 
    println("--------Write method of Kryo") 
    } 
} 

object User { 
    def apply(name: String, age: Int = 0): User = new User(name, age) 
} 
1

由於User是一個案例類,你可以使用copy創建一個新的User同時更新(部分)價值。

case class User(name: String = "", age: Int = 0) 

val empty = User() // User = User(,0) 
val alice = empty.copy("Alice", 40) // User = User(Alice,40) 

但自從與KryoSerializable您需要修改的對象本身(的read類型是Unit),你不能返回一個新的User實例,所以你會使用外部Serializer[User]的更好,如果你想繼續使用案例類。

class UserSerializer extends Serializer[User] { 
    def write (kryo: Kryo, output: Output, user: User): Unit = { 
    output.writeString(user.name) 
    output.writeInt(user.age) 
    } 

    def read(kryo: Kryo, input: Input, `type`: Class[User]): User = 
    User(
     name = input.readString() 
     age = input.readInt() 
    ) 
}