代码之家  ›  专栏  ›  技术社区  ›  Joe

scala风格的元素?[关闭]

  •  43
  • Joe  · 技术社区  · 15 年前

    我白天写C。我所做的一切都是通过Microsoft代码分析和静态分析工具完成的,因此我的C具有非常规则的结构和布局。显然,我用某种风格编写代码。部分原因是因为我没有选择(如果我漏掉了逗号前面的一个空格,它就不会编译),但是有正规的代码、知道在哪里查找东西等也是很好的。

    周末我要去斯卡拉。查看scala API和 Lift Web框架源代码,我显然看不到任何标准化的样式。例如,我突然想到的一件事是,每个类缺少单独的文件。另一个例子是缺乏与括号和大括号的一致性。

    我理解驱动这一点的原因可能有几个:首先,使用开放源码(或业余爱好)代码,确保一个明显的方法没有被完全记录在案,这就不那么重要了。其次,case类将20行类声明缩减为一行。第三,C是一种非常“恭维”的语言:除非它是一种复杂的语言。 LINQ 语句,嵌套parens、大括号和方括号的数目没有那么深。在scala中,事情往往有点嵌套。

    普通的scala用户有他们坚持的特定风格吗?为了[外星人]的习俗,我把一行的case类放在自己的文件里是不是很愚蠢?有什么小窍门吗?

    5 回复  |  直到 12 年前
        1
  •  45
  •   Daniel C. Sobral    12 年前

    在scala中,在一个文件中包含多个类和对象被认为是很好的形式,只要这些类是紧密相关的。

    虽然不是必需的,但方法(在特性、类或对象上声明的命名函数)返回的类型应为非私有方法声明。后面需要空格 : 但不是在它之前。

    //  methods declared on a class, trait or object
    def length: Int = ...
    def multiply(other: Foo): Foo = ...
    
    def hypotenuse(a: Double, b: Double): Double = {
      //  function inside a method, so effectively private
      def square(x: Double) = x * x
    
      math.sqrt(square(a) + square(b))
    }
    

    在点表示法中,关键字和括号之间应该有空格,但方法名和以下括号之间不应该有空格。对于运算符表示法,对于圆括号或何时使用该表示法,似乎没有一种可接受的样式,但在这种表示法中,非字母数字方法周围应该有空格。

    //  keywords
    if (foo) ...
    
    //  dot notation
    foo.doSomething(bar)
    
    //  operator notation
    foo doSomething bar
    foo + bar
    

    异常情况下,将字符串与 + ,建议不要在其周围使用空格。例如:

    //  concatenate strings
    println("Name: "+person.name+"\tAge: "+person.age)
    

    可以是一行程序的声明应该是一行程序,除非嵌套不明显。

    //  one-liners
    lazy val foo = calculateFoo
    def square(x: Int) = x * x
    

    不期望参数而不具有副作用的方法,除了括号内的Java方法外,不需要括号使用。带副作用的无参数方法应该与括号一起使用。

    //  without side-effects
    val x = foo.length
    val y = bar.coefficient
    
    //  with side-effects
    foo.reverse()
    

    包含单个表达式的声明不应包含在大括号内,除非其他语法考虑使其不可能。将表达式括在括号内以启用多行表达式是可以接受的,但我很少看到这种用法。

    //  single-line expression
    def sum(list: List[Int]): Int = if (!list.isEmpty) list reduceLeft (_ + _) else 0
    
    //  multi-line expression
    val sum = (
      getItems
      reduceLeft (_ + _)
    )
    

    在理解方面,保持生成器和条件垂直对齐似乎是一种公认的风格。至于 yield ,我已经看到它与 for 缩进。

    //  for-comprehensions
    val squares =
      for (x <- numbers)
        yield x * x
    
    // Curly brackets-style identation
    val cells = for {
      x <- columns
      y <- rows
      if x != y
    } yield Cell(x, y)
    
    // Parameter-style identation
    val cells = for (x <- columns;
                     y <- rows;
                     if x != y)
                yield Cell(x, y)
    

    它还接受了垂直对齐类声明参数的样式。

    说到缩进,两个空格是公认的惯例。

    大括号应该从声明的同一行开始,并单独与该行垂直对齐。

    //  another example
    def factorial(n: Int): Int = {
      def fact(n: Int, acc: Int): Int = n match {
        case 0 => acc
        case x => fact(x - 1, x * acc)
      }
    
      fact(n, 1)
    }
    

    对于过程--返回类型为 Unit --,预期的样式应该是省去方法的类型和等号:

    //  procedures
    def complain {
      println("Oh, no!")
    }
    

    但是,有些人认为这种样式容易出错,因为遗漏的等号会改变返回其他类型的函数 单位 进入一个程序。

    标识符以camel大小写(例如: identifiersHaveHumps ),就像在Java中一样。对于字段、方法参数、局部变量和函数的名称,从小写字母开始。对于类、特性和类型,从大写字母开始。

    离开Java约定是常量名称。在scala中,实践是使用标准的camel大小写,从大写字母开始。例如 Pi 而不是 PI ,xoffset和not X_OFFSET . 这条规则通常后面跟着任何一个单例。用这种方式表示常量和单子具有实际的结果,对于case匹配:

    import scala.Math.Pi
    
    val pi = Pi // this identifier will be shadowed by the identifier in the function below
    
    def isPi(n: Double): Boolean = n match {
      case Pi => println("I got a true Pi."); true
      case pi => println("I got "+pi+" and bounded it to an identifier named pi."); false
    }
    

    包名称以小写字母开头。当在导入语句中区分什么是包,什么不是包时,这特别有用。在前面的示例中, Math 不是一个包(它是一个单例),因为它以大写字母开头。

    使用下划线字符-- _ --不建议使用,因为该字符在scala中有许多特殊的含义。这些标识符规则可以在scala编程的第141和142页找到,由Odersky、Spoon&Venners提供。

    现在,我想不起来其他情况了,但我可以要求澄清具体问题。其中一些规则是明确规定的,另一些则更像是社区共识。我试着省去自己的偏好,但可能失败了。

    更重要的是,可能只是没有太多的统一惯例。其中一个原因可能是斯卡拉吸引了许多不同背景的人,如功能语言专家、Java程序员和Web 2爱好者。

        2
  •  12
  •   Daniel Spiewak    15 年前

    现在有一个完整的scala风格指南 proposed to the community . 它甚至还不是远程官方的,但它是唯一(据我所知)被社区接受的公约的编纂。

        3
  •  7
  •   kolen    12 年前

    现在 Scala Style Guide 是可用的。它不是100%官方的(位于 Community-driven documentation for Scala “site”),但似乎是scala最标准的样式指南。

        4
  •  2
  •   Daniel Spiewak    15 年前

    这是一个非常重要的问题。一般来说,scala风格似乎是通过与scala社区的其他成员一起闲逛、阅读scala源代码等来获得的。这对新加入该语言的人没有太大帮助,但它确实表明某种事实上的标准 存在(由群众的智慧选择)。我目前正在为scala编写一个完全实现的风格指南,其中记录了社区选择的惯例和最佳实践。但是,A)还没有完成,B)我还不确定是否允许我发表(我是为了工作而写)。

    回答第二个问题(排序):一般来说,每一个类/特征/对象都应该得到自己的文件,该文件是根据Java命名约定命名的。但是,在有许多类共享一个共同概念的情况下,有时将它们全部放入同一个文件中是最容易的(短期和长期)。当您这样做时,文件名应该以小写字母(仍然是camelcase)开头,并描述共享概念。

        5
  •  2
  •   Peter Mortensen icecrime    12 年前

    我不太喜欢很多Scala编码器使用的典型样式,所以我只是应用了我在C语言、Java或JavaScript中使用的相同的标准。

    斯卡拉 可以 表现力很强,但是使用不熟悉的格式会增加你进入的障碍。特别是考虑到内部 DSLs 不可能有“标准”。

    所以,我要做任何能让你和你的团队更容易阅读你的代码的事情。