【天贏金創】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--- (未完待續)

相關文章
相關標籤/搜索