需要澄清scala中的构造函数定义语法吗

需要澄清scala中的构造函数定义语法吗,scala,Scala,我是scala新手,需要澄清以下涉及类构造函数的代码片段 class sample (a: Int, b: Int) { /* define some member functions here */ } 我可以假定变量a和b是类sample的私有变量吗 class sample (val a: Int, val b: Int) { /* define some member functions here */ } 在这种情况下,a和b是否可以公开访问?在构造函数的参数列表中添加val关键字

我是scala新手,需要澄清以下涉及类构造函数的代码片段

class sample (a: Int, b: Int) {
/* define some member functions here */
}
我可以假定变量
a
b
是类
sample
的私有变量吗

class sample (val a: Int, val b: Int) {
/* define some member functions here */
}
在这种情况下,
a
b
是否可以公开访问?在构造函数的参数列表中添加
val
关键字的确切效果是什么?如果我使用
def
关键字而不是
val
,它是否也有相同的效果

class sample (a: Int, b: Int)
在这种情况下,a和b是私有的。使用javap进行反汇编显示a和b不是类的一部分(Scala调用这些类字段):

a和b前面带有val。使用javap进行反汇编显示a和b现在是示例中的公共字段

类样本(val a:Int,val b:Int)

使用构造函数中的
def
而不是
val
,它将不会编译<代码>定义用于定义函数。不确定是否可以在构造函数中使用
def
作为参数

另外,请注意,private和protected的行为与您预期的一样。鉴于此:

class Sample(private val a: Int, protected val b: Int, val c: Int)
使用javap分解为以下内容:

public class Sample extends java.lang.Object implements scala.ScalaObject{
    public int b();
    public int c();
    public Sample(int, int, int);
}

下面的Scala类显示了构造函数参数的四种可能性(3种不同的声明,其中一种有两种效果):

  • 第一个参数,
    local
    ,没有被任何方法引用。它仅作为构造函数中的局部变量存在(字段初始值设定项可以引用它,而无需更改;请尝试将
    val foo=local
    添加到构造函数中)
  • 第二个,
    prvt
    ,由一个方法引用,因此它成为一个私有字段
  • 第三个上的
    val
    声明符创建一个getter和一个私有支持字段
  • 第四个上的
    var
    声明器创建了一个getter和setter,以及一个私有支持字段
  • 特别要注意的是,没有
    val
    var
    声明符的构造函数参数只有在类中的函数中引用时才是私有的(这是一个可访问性问题);否则,它是局部的(这是一个范围问题)

    从技术上讲,最后三个参数以局部值和私有字段(初始化为局部值)的形式存在,但这种区别不应该出现太多,因此您可以将其排除在外

    def
    作为参数声明符没有多大意义,因为它用于引入新函数,而不是声明值/变量名;它也不用于函数参数(构造函数参数与函数参数密切相关)。因为函数是第一类,所以可以使用函数类型而不是特殊的声明符来声明参数包含函数

    通过将
    -Xprint:constructors
    传递给编译器,打印出编译器对
    ConstructorParams
    的内容,我们得到(添加注释):

    如果在构造函数参数上使用
    javap
    (正如Brian所做的那样)和
    -p
    参数,您将看到一个与上述Java源代码中的类签名等效的类签名

    class Sample(private val a: Int, protected val b: Int, val c: Int)
    
    public class Sample extends java.lang.Object implements scala.ScalaObject{
        public int b();
        public int c();
        public Sample(int, int, int);
    }
    
    class ConstructorParams (local:Int, prvt:Int, val readonly:Int, var writable:Int) {
      def succ_prvt() = prvt + 1
    }
    
    class ConstructorParams extends Object {
        /* 2nd (no-declarator) param becomes private field due to reference in `succ_prvt()` */
        <paramaccessor> private[this] val prvt: Int = _;
    
        /* `val` becomes private field + getter */
        <paramaccessor> private[this] val readonly: Int = _;
        <stable> <accessor> <paramaccessor> def readonly(): Int = ConstructorParams.this.readonly;
    
        /* `var` becomes private field + getter + setter */
        <paramaccessor> private[this] var writable: Int = _;
        <accessor> <paramaccessor> def writable(): Int = ConstructorParams.this.writable;
        <accessor> <paramaccessor> def writable_=(x$1: Int): Unit = ConstructorParams.this.writable = x$1;
    
        /* causes `prvt` constructor param to become private field */
        def succ_prvt(): Int = ConstructorParams.this.prvt.+(1);
    
        def <init>(local: Int, prvt: Int, readonly: Int, writable: Int): ConstructorParams = {
            ConstructorParams.this.prvt = prvt;
            ConstructorParams.this.readonly = readonly;
            ConstructorParams.this.writable = writable;
            ConstructorParams.super.<init>();
            ()
        }
    }
    
    public class ConstructorParams {
        /* 2nd (no-declarator) param becomes private field due to reference in `succ_prvt()` */
        private final int prvt;
    
        public int succ_prvt() {
            return this.prvt + 1;
        }
    
        /* `val` becomes private field + getter */
        private final int readonly;
        public int readonly() { return this.readonly; }
    
        /* `var` becomes private field + getter + setter */
        private int writable;
        public int writable() { return this.writable; }
        public void writable_$eq(int x$1) {
            this.writable = x$1;
        }
    
        /* 1st param is local, since it's not referenced in any other methods */
        public ConstructorParams(int local, int prvt, int readonly, int writable) {
            /* parent constructor is invoked implicitly, so not repeated here */
            this.prvt = prvt;
            this.readonly = readonly;
            this.writable = writable;
        }
    }