Scala mutator命名约定和要求

时间:2016-01-13 00:06:51

标签: scala properties naming-conventions

我在修改Scala中有关mutator的命名方面遇到了一些麻烦。以下是我无法理解的部分:

class Company {
  private val _name: String = _

  def name = _name

  def name_=(name: String) {
    _name = name
  }
}

所以我理解_name是私有String,第一个def名称是getter / accessor,而第二个是setter / mutator。从本质上讲,我理解代码的含义和作用,但我不确定什么是个人偏好与代码标准/所需的方法。是否所有mutator都具有_后缀,并且使用下划线为私有属性添加前缀是标准的还是个人偏好?

或者我可以将mutator定义为以下内容吗?

def name=(name: String) {
    _name = name
}

同样,我是否使用下划线将私有val作为前缀,或者我可以将其更改为:

def name=(name: String) {
   name = name
}

我从Scala Naming ConventionsDaniel Spewak's Accessors/Mutators

获得了上述代码

1 个答案:

答案 0 :(得分:0)

这些都是好问题。您喜欢的Scala文档中的文章(特别是关于Accessors/Mutators的那部分)涵盖了其中的一些内容。

变异方法的命名

简而言之,name_=格式不是特殊的语法,而是由规范强制执行的命名约定。

让我们看看在声明普通的旧scalac时,var在JVM字节码级别产生了什么。不需要理解scalac产生的字节码来理解该语言的更高层次的工作,但是许多学习Scala的人都有一定的Java经验,尽管这对JVM中可能的功能有一些直觉什么不是。我认为这是我们最接近的,作为Scala规范中做出的某些决定的为什么

这里有一个名为Var.scala的源文件:

trait Var {
  var name: String
}

我将源代码编译为 class文件,然后使用javap对其进行反编译:

$ scalac Var.scala 
$ javap Var.class 
Compiled from "Var.scala"
public interface Var {
  public abstract java.lang.String name();
  public abstract void name_$eq(java.lang.String);
}

我们可以看到,特征中的var声明了两个JVM方法,一个getter和一个setter。 getter的名称为var,而setter的名称有点怪异。在这里,$eq就是Scala标识符中的=在其生成的类文件中由scalac编码的方式。这是Scala规范的一部分,是不同编译单元之间的二进制兼容性所必需的。

因此,从Scala中看到的二传手的名字就是name_=。这也是Scala规范的一部分。当我们编写设置var值的语句时,将生成对该形式名称的方法的调用。当我们编写仅读取var的语句时,将生成对第一个方法的调用。

除了声明var之外,我们还可以直接声明这两个方法:

trait ValAndDef {
  val name: String
  def name_=(newName: String): Unit
}

编译和反编译将显示与以前完全相同的方法。也没有什么可以阻止您仅声明其中一种方法,该方法将创建只能读取但不能写入的成员,反之亦然。

私人包装字段的命名

直到现在,我只谈论了声明字段。 实施字段表示在直接声明时也向var添加存储或实现方法。在 class 中声明var而不是 trait 将自动添加一个字段,用于存储var的值:

class VarClass {
  var name: String = _
}

$ javap -private VarClass.class
Compiled from "VarClass.scala"
public class VarClass {
  private java.lang.String name;
  public java.lang.String name();
  public void name_$eq(java.lang.String);
  public VarClass();
}

如果您决定使用一对方法来实现该字段,则必须自己声明一个私有字段。 Scala规范没有说明在那种情况下该字段的命名方式(它是私有的,因此不属于任何互操作性问题)。

我唯一能找到的“官方”是我在顶部链接的文章中的一段,该段落提倡_name支持字段的命名模式,同时指出:

  

尽管匈牙利表示法十分丑陋,但确实具有消除_name变量歧义而又不会使标识符混乱的优点。

因此,是否要遵循该指南取决于您。 ¯\ _(ツ)_ /¯