博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【天赢金创】Crystal 语言
阅读量:6321 次
发布时间:2019-06-22

本文共 2410 字,大约阅读时间需要 8 分钟。

Beautiful Syntax, Faster Than Go

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

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

除了编译外, 和 Elixir 的区别还有: 它的语法和 Ruby 很相似, 所以 Crystal 编译器可以直接用 Crystal 和 Ruby 的交集写, 然后用 Ruby 执行编译自己, 就轻松完成了 bootstrap. 它的语法对熟悉 Ruby 的人更有亲和力, 所以 Matz 率先捐了 $500.

所以你看, 虽然现在还在 Alpha 阶段, 还是很有存在意义的.


Crystal 还有一些与众不同的特性:

面向对象类型推导

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

举个栗子:

class Person  getter name  def initialize @name  endenddaisy = Person.new "Daisy Johnson"chappie = Person.new 22puts daisy.inspectputs 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" : 42if a.is_a? String  # 这里 a 的类型是 String  puts a.sizeelse  # 这里 a 的类型是 Int32  puts a / 2end

Nil 的处理

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

a = some_condition ? nil : 3# a is Int32 or Nilif a  # Since the only way to get here is if a is truthy,  # a can't be nil. So here a is Int32.  a.absend

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

if @a  @a.abs # 如果编译器分析出 @a 可以赋值 nil, 就会出编译错误end

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

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

和 Ruby 一样, 由于 Nil 上可以定义方法, 所有值都自然变成 Maybe Monad 了, 上面的代码也可以改成用 try 去处理

@a.try do |a|  a.absend

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

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

不那么静态

从上面可以看到, 和一般的静态语言相比, Crystal 的一个局部变量的类型并不是固定的

a = 32 # 现在 a 的类型是 Int32a.absa = "foo" # 现在 a 的类型是 Stringa.length

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

a = 1while 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 Boolenda               # here a is Int32 or String or Bool

来自知乎

--- (未完待续)

转载地址:http://ikjaa.baihongyu.com/

你可能感兴趣的文章
iOS 快速注释工具VVDocumenter-加强版支持Xcode 7
查看>>
react 入门学习
查看>>
发布-订阅方式实现异步并发
查看>>
程序员只拿到5千工资吐槽无法生活,网友:别在意薪资
查看>>
使用React、Electron、Dva、Webpack、Node.js、Websocket快速构建跨平台应用
查看>>
JVM之类加载机制
查看>>
JVM如何获取当前容器的资源限制
查看>>
flask-restful 大型项目结构示例
查看>>
JavaScript 精粹 基础 进阶(2)表达式和运算符
查看>>
用gulp搭建小程序开发编译环境
查看>>
js基础语法(1)
查看>>
Java线程同步的几种方式
查看>>
Lambda
查看>>
将本地图片上传至七牛云
查看>>
【深入浅出ES6】Class
查看>>
addEventListener中的EventListener接口对象
查看>>
css3 transform,translate,animation
查看>>
学习Python for Data Science:在数据科学中使用Python库
查看>>
Julia 1.0 中文文档
查看>>
删除数组中指定的一个或多个对象
查看>>