为什么Scala选择在变量名后面加上类型?

Roh*_*hit 36 scala

在Scala中,变量声明为:

var stockPrice: Double = 100.
Run Code Online (Sandbox Code Playgroud)

其中类型(Double)遵循标识符(stockPrice).传统上,在诸如C,Java,C#等命令式语言中,类型名称在标识符之前.

double stock_price = 100.0;
Run Code Online (Sandbox Code Playgroud)

这纯粹是一种品味问题,或者最终是否有类型名称以任何方式帮助编译器?Go也有相同的风格.

Mar*_*sky 65

凯文说得对.主要观察是"类型名称"语法效果很好,只要类型是短关键字,如intfloat:

int x = 1
float d = 0.0
Run Code Online (Sandbox Code Playgroud)

以1的价格获得两条信息:"新定义从这里开始","这里是定义的(结果)类型".但是我们现在已经超越了简单原始类型的领域.如果你写

HashMap<Shape, Pair<String, String>> shapeInfo = makeInfo()
Run Code Online (Sandbox Code Playgroud)

您定义的最重要的部分(名称)隐藏在类型表达式后面.与之比较

val shapeInfo: HashMap[Shape, (String, String)] = makeInfo()
Run Code Online (Sandbox Code Playgroud)

它清楚地说

  • 我们在这里定义一个值,而不是变量或方法(val)
  • 我们定义的东西的名称是shapeInfo
  • 如果您关心它,这里是类型(HashMap [...])


Kev*_*ght 51

除了支持类型推断,这也有一个符合人体工程学的好处.

对于任何给定的变量名+类型,可能是名称是更重要的信息.向左移动使其更加突出,一旦您习惯了这种风格,代码就更具可读性.

其他人体工程学优点:

  • 随着val,vardef前成员名称,而不是它们的类型,它们都整齐地列排队.
  • 如果你只更改一个成员的类型,或者完全放弃它以支持推理,那么一个细粒度的diff工具将清楚地表明该名称是未改变的
  • 同样,在差异中,val/var/def之间的变化非常明显
  • 推理应该被认为是Scala中的默认行为,您只需要在某些特定场景中使用类型规范,即使这样,它主要是针对编译器完成的.所以把它们放在声明的最开始就强调错误的东西.
  • "name:Type"而不是"Type name"更接近于大多数程序员实际考虑声明的方式,它更自然.
  • 指针和数组的不同C/C++和Java约定(即*在以下名称上作为前缀而不是C/C++中前一类型的后缀,或者[]是Java中名称和类型的有效后缀)仍然令人困惑对新手或语言转换,并在单行上声明多个变量时会导致一些非常真实的错误.斯卡拉在这里没有任何怀疑和困惑的余地.

  • 我认为像Eclipse这样的Java IDE也首先显示名称也很有趣.不在源代码中,而是在代码大纲中. (9认同)

Dan*_*ral 15

之后它可以被移除以进行类型推断:

var stockPrice: Double = 100.0
var stockPrice = 100.0
Run Code Online (Sandbox Code Playgroud)

然而,命令式语言传统上首先具有类型并不是事实.例如,Pascal没有.

现在,C做到了,而C++,Java和C#都是基于C的语法,所以他们自然也是这样做的,但这绝对与命令式语言无关.

  • @Raphael如果它是用Java编写的,`Double stockPrice = 10.0`,那么删除该类型会使它成为`stockPrice = 10.0`,这不是声明.实际上,C#必须引入一个关键字才能使类型推断成为可能,这限制了可以将类型推断到关键字可能出现的位置的位置.在Scala中,您只需根据需要添加或删除类型. (6认同)
  • 我认为特别是类型定位不能让它们脱离. (4认同)

Dav*_*ith 5

应该注意的是,即使C"传统上"也没有在变量名之前定义类型,但实际上允许声明是交错的.

int foo[];
Run Code Online (Sandbox Code Playgroud)

在词法之前和之后声明foo类型的地方.

除此之外,我猜这是一个没有区别的区别.编译器开发人员肯定不会这样或那样.