对Scala类定义感到困惑

Kua*_*uan 0 scala

所有:

我是斯卡拉研究的第三天.使用书"开始scala".

它定义了一个类:

class Book( var title:String)
Run Code Online (Sandbox Code Playgroud)

然后实例化一个对象:

val book = new Book("Beginning Scala")
Run Code Online (Sandbox Code Playgroud)

它提到了一件事

如果您反编译此代码,您可以看到生成的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")
Run Code Online (Sandbox Code Playgroud)

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

book.title("new title")
Run Code Online (Sandbox Code Playgroud)

scala控制台告诉我:

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

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

谢谢

Arn*_*sen 5

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

book.title = "Beginning Scala"
Run Code Online (Sandbox Code Playgroud)

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

book.title_$eq("Beginning Scala")
Run Code Online (Sandbox Code Playgroud)

如果你想手动设置getter和setter,你会写这样的东西:

class Book() {
  private var _title = ""
  def title = _title
  def title_=(v: String):Unit = _title = v
}
Run Code Online (Sandbox Code Playgroud)

允许你这样做:

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"
Run Code Online (Sandbox Code Playgroud)

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