对Scala类定义感到困惑

时间:2015-08-12 04:49:42

标签: scala

所有

我正在进行斯卡拉研究的第三天。使用书“开始scala”。

它定义了一个类:

class Book( var title:String)

然后实例化一个对象:

val book = new Book("Beginning Scala")

它提到了一件事

  

如果您反编译此代码,则可以看到生成的mutator方法   有一个不寻常的名字,title_ $ eq。

scala> :javap -c Book
Compiled from "Book.scala"
public class Book {
public java.lang.String title();
//.......
public void title_$eq(java.lang.String);
//.........
public Book(java.lang.String);
//........
}

So when you set the field, like so

book.title("new title")

Scala converts it to the following:

Book.title_$eq("Beginning Scala")

我不确定我是否理解这一点,但是当我尝试时:

book.title("new title")

scala控制台告诉我:

<console>:13: error: type mismatch;
 found   : String("new title")
 required: Int
       book.title("new title")

我想知道scala是否不允许外部调用setter函数,为什么作者会这样提到?

由于

1 个答案:

答案 0 :(得分:5)

有关反编译的部分试图告诉您的是它实际上将访问者设置为可分配的,例如:

book.title = "Beginning Scala"

这是可能的,因为赋值实际上只是自动生成的方法`Book.title_ $ eq(v:String)的语法糖。如果你愿意,你可以使用那个长形式:

book.title_$eq("Beginning Scala")

如果你想手动设置getter和setter,你可以这样写:

class Book() {
  private var _title = ""
  def title = _title
  def title_=(v: String):Unit = _title = v
}

允许你这样做:

val book = new Book()
book.title = "bar"
println(book.title) // "bar"
book.title_=("foo")
println(book.title) // "foo"
book.title_$eq("baz")
println(book.title) // "baz"

如您所见,title_=方法可以通过赋值语法糖,_=方法或_$eq编码来使用。