【天赢金创】Crystal 语言

Beautiful Syntax, Faster Than Go编程

它和 Mirah, JRuby, Groovy 等等的区别是: 它不须要 JVM 这个平台, 没有字节码和解释器. 很容易在速度上超过这些 JVM 语言.bootstrap

一样是编译成 LLVM IR 再到机器码, 和 Ruby Motion 的区别是: Ruby Motion 依赖 ObjC 运行时, 而 Crystal 不依赖安全

除了编译外, 和 Elixir 的区别还有: 它的语法和 Ruby 很类似, 因此 Crystal 编译器能够直接用 Crystal 和 Ruby 的交集写, 而后用 Ruby 执行编译本身, 就轻松完成了 bootstrap. 它的语法对熟悉 Ruby 的人更有亲和力, 因此 Matz 率先捐了 $500.app

因此你看, 虽然如今还在 Alpha 阶段, 仍是颇有存在乎义的.线程


Crystal 还有一些不同凡响的特性:code

面向对象类型推导对象

在一些静态类型系统上结合 FP 和面向对象的尝试中, 例如 Scala 中, 推导仅局限于方法内部. 而 Crystal 没有这个限制, 它会尽可能修改类型定义以知足使用须要文档

举个栗子:get

class Person
  getter name

  def initialize @name
  end
end

daisy = Person.new "Daisy Johnson"
chappie = Person.new 22

puts daisy.inspect
puts chappie.inspect

使用 hierarchy 命令查看类图编译器

$ crystal hierarchy person.cr
...
+- class Person (24 bytes)
     |      @name : (String | Int32) (16 bytes)
...

能够看到 Person 的 name 属性的类型自动变成了 String | Int32

if 表达式类型推导

和 Ruby 同样, Crystal 的 if 语句有返回值, 是表达式. 但 if 表达式在不少静态语言中的使用却不那么便利, 一个巨大问题就是编译器不能根据条件去作推断, 例如:

val a = if (args.length > 0) { "string" } else { 42 } // a 的类型是 Any
if (a.isInstanceOf[String]) {

println(a.length) // 编译错误, Any.length 没定义, 得手动强转

}

而 Crystal 的类型推断会考虑条件中的 is_a? 和 responds_to? 信息, 减小了繁琐的强制转换:

a = ARGV.size > 0 ? "string" : 42
if a.is_a? String
  # 这里 a 的类型是 String
  puts a.size
else
  # 这里 a 的类型是 Int32
  puts a / 2
end

Nil 的处理

在静态类型语言中, 有的编译器默认容许 nil/null, 那么就会抛出 NPE (NullPointerException), 有的编译器会在类型上禁止一些 nil/null 的存在, 并鼓励用 Maybe/Option 去装箱/拆箱. 前一种方法很容易出错, 后一种方法使用繁琐 (尤为在不支持 do notation 的语言中). 而 Crystal 结合数据流分析, 对 nil 值的处理更加简单优雅. 文档里的例子以下:

a = some_condition ? nil : 3
# a is Int32 or Nil

if a
  # Since the only way to get here is if a is truthy,
  # a can't be nil. So here a is Int32.
  a.abs
end

不过为了线程安全, 非局部变量不推荐这么作

if @a
  @a.abs # 若是编译器分析出 @a 能够赋值 nil, 就会出编译错误
end

上面的代码能够加锁, 或者改写成局部变量判断的方式

if a = @a
  a.abs # 别的线程就改不了局部变量啦
end

和 Ruby 同样, 因为 Nil 上能够定义方法, 全部值都天然变成 Maybe Monad 了, 上面的代码也能够改为用 try 去处理

@a.try do |a|
  a.abs
end

在 responds_to 的情形, 会出现这类代码 pattern

if (a = @a).responds_to? :size
  a.size
end

不那么静态

从上面能够看到, 和通常的静态语言相比, Crystal 的一个局部变量的类型并非固定的

a = 32 # 如今 a 的类型是 Int32
a.abs
a = "foo" # 如今 a 的类型是 String
a.length

在 while 循环中, 编译器会作更复杂的事情, 尽可能不让类型成为阻碍编程的限制, 如下例子出自 Crystal 博客:

a = 1
while some_condition
  a             # here a is Int32 or String or Bool
  if some_other_condition
    a = "hello" # we next, so in the next iteration a can be String
    next
  end
  a = false     # here a is Bool
end
a               # here a is Int32 or String or Bool

来自知乎
http://www.zhihu.com/question/33311554--- (未完待续)

相关文章
相关标签/搜索