scala类构造函数参数

zih*_*oyu 46 constructor scope scala immutability

有什么区别:

class Person(name: String, age: Int) {
  def say = "My name is " + name + ", age " + age
}
Run Code Online (Sandbox Code Playgroud)

class Person(val name: String, val age: Int) { 
  def say = "My name is " + name + ", age " + age
}
Run Code Online (Sandbox Code Playgroud)

我可以将参数声明为vars,并在以后更改它们的值吗?例如,

class Person(var name: String, var age: Int) {

  age = happyBirthday(5)

  def happyBirthday(n: Int) {
    println("happy " + n + " birthday")
    n
  }
}
Run Code Online (Sandbox Code Playgroud)

om-*_*nom 48

对于第一部分,答案是范围:

scala> class Person(name: String, age: Int) {
     |   def say = "My name is " + name + ", age " + age
     | }

scala> val x = new Person("Hitman", 40)

scala> x.name
<console>:10: error: value name is not a member of Person
              x.name
Run Code Online (Sandbox Code Playgroud)

如果您使用参数前缀val,则var它们将在课外显示,否则,它们将是私有的,您可以在上面的代码中看到.

是的,你可以改变var的值,就像通常一样.

  • 它比公共/私人区别更微妙.如果没有属性关键字(`val`或`var`),构造函数参数只有在方法体中使用时才会存储在字段中.如果它们仅在构造函数中使用,则_and_不以`var`或`val`作为前缀,那么它们根本不存在于构造函数之外.如果实例的大小很重要,请注意是否在方法体中引用了非属性构造函数参数. (27认同)
  • 此外,范围和可访问性是不同的东西. (2认同)
  • 在这种情况下,Scala编译器将发出一个私有字段,如果你查看生成的字节码,你会看到`private final Z fake`. (2认同)

Bri*_*new 10

这个

class Person(val name: String, val age: Int)
Run Code Online (Sandbox Code Playgroud)

使字段的用户可以在外部使用,例如,您可以稍后进行

val p = new Person("Bob", 23)
val n = p.name
Run Code Online (Sandbox Code Playgroud)

如果将args指定为var,则范围与for相同val,但字段是可变的.


yxj*_*ang 8

如果您熟悉Java,可以从这个示例中获得想法:

class Person(name: String, age: Int)
Run Code Online (Sandbox Code Playgroud)

类似于

class Person {
  public Person(String name, int age) {
  }
}
Run Code Online (Sandbox Code Playgroud)

class Person(var name: String, var age: Int) // also we can use 'val'
Run Code Online (Sandbox Code Playgroud)

类似于

class Person {
  String name;
  int age;

  public Person(String name, int age) {
     this.name = name;
     this.age = age;
  }
}
Run Code Online (Sandbox Code Playgroud)

直觉是没有var/val,变量只能在构造函数中访问.如果添加了var/val,则该类将具有相同名称的成员变量.

  • 第一次比较并不完全正确.在Java代码中,您可以在构造函数中调用参数`name`和`age`,而不是在其他类方法中,但在Scala中,您可以.Java中类似的代码是:`class Person {private String name; 私人年龄; public Person(String name,int age){this.name = name; this.age =年龄; } (2认同)