4 August 2022

scala databricks 编码规范阅读记录

原文链接-移步阅读

记录

本文只记录一些作者本人之前不太了解或者违背较多的的编码规范

  1. 样例类避免可变的var 出现. 之前从java 转scala 的开发者可能不太习惯不可变类型,造成编码出现问题

     // This is OK
     case class Person(name: String, age: Int)
    
     // This is NOT OK
     case class Person(name: String, var age: Int)
    
     // To change values, use the copy constructor to create a new instance
     val p1 = Person("Peter", 15)
     val p2 = p1.copy(age = 16)
    
     case class Report(name:String,age:Int,score:Int,height:Int,weight:Int)
    
     object Report{
    
     def updateReport(report:Report,update:Int=>Report=>Report,value:Int)={
         update(value)(report)
     }
    
     }
    
    
  2. apply 方法 应该定义在 object 中 且应该返回 companion class type

     object TreeNode {
     // This is OK
     def apply(name: String): TreeNode = ...
    
     // This is bad because it does not return a TreeNode
     def apply(name: String): String = ...
     }
    
  3. 参数绑定 不要在构造代码块中使用 ,尤其是transient 中 Destructuring bind (sometimes called tuple extraction)
     class MyClass {
     // This will NOT work because the compiler generates a non-transient Tuple2
     // that points to both a and b.
     @transient private val (a, b) = someFuncThatReturnsTuple2()
     }
    
  4. 传名函数 Avoid using call by name(: => T). Use () => T explicitly

  5. return 的使用
    • 不要再闭包中使用return //todo 有实践研究一下
    • 可以在终止循环中使用return,而不是 flag
  6. 异常处理
    • 使用 scala.util.control.NonFatal 替代 Throwable 或者 Exception
    • 不要在API 中使用Try,也就是函数返回值是 Try(T),因为语义不详会导致多层嵌套,直接使用java 风格的trycatch
    • 使用Option 替代null(For performance sensitive code, prefer null over Option, in order to avoid virtual method calls and boxing. Label the nullable fields clearly with Nullable.)
      class Foo {
      @javax.annotation.Nullable
      private[this] var nullableField: Bar = _
      }
      

个人理解

对整篇编码规范的阅读下来,发现编码规范主要处理以下几方面问题

  1. 编译后的代码的稳定性 类似方法签名在重载过程中导致模棱两可效果
  2. 与java 的兼容性 abstract class 替代 trait,显式添加varargs 标记
  3. 代码的可读性 比如在匿名函数使用中避免过多的 小括号大括号嵌套, Long 类型的字面量使用大写的L 而不是小写的容易和1混淆的l 编码过程中不同类型变量命名遵顼约定的规范等。apply 方法定义在object中
  4. 性能问题 使用while 替代 map for 等循环,性能敏感区块使用 null 替代None 等

    以前的笔记

  5. 命名约定
  6. 1行长度100字符以内
  7. 避免使用中缀表示法
  8. 避免使用多余的小括号和花括号
  9. 实现抽象方法使用oveerride 修饰符
  10. 避免使用按名传参
  11. 尾递归使用注解@tailrec
  12. 不要捕获Throwable 或 Exception 使用 scala.util.control.NonFatal
  13. 如果一个值可能为空 使用 Option
  14. 使用private[this]
  15. 性能(在有性能要求的时候) a. 使用while 而非for 或者map,foreach , b. 使用microbenchmark c. 使用null 而非 Option d. 优先使用JAVA 集合
  16. java 通用性 a. 默认方法实现的trait 无法在 java中使用,使用 抽象类代替 b. 类型别名 c. 默认参数值 d. 多参数列表 e. 可变参数,使用@scala.annotation.varargs
  17. 优先使用 nanoTime,则可以保证是单调递增的
  18. 优先使用经过良好测试的方法

编码规范可以理解开发团队在长期的生产实践中总结的经验,遵循这些规范可以避免在后续的团队开发协作中形成统一风格,避坑