GitHub 仓库 论坛 RSS-新闻源

Crystal

为人类和计算机设计的语言

示例

内置电池

Crystal 的标准库包含了一系列库,让您能够立即开始您的项目。

# A very basic HTTP server
require "http/server"

server = HTTP::Server.new do |context|
  context.response.content_type = "text/plain"
  context.response.print "Hello world, got #{context.request.path}!"
end

address = server.bind_tcp(8080)
puts "Listening on http://#{address}"

# This call blocks until the process is terminated
server.listen

类型系统

Crystal 是静态类型语言,类型错误在编译时被捕获,消除了运行时一系列类型相关的错误。

由于强大的类型推断,类型注释很少需要。这保持了代码的简洁,感觉就像动态语言一样。

def shout(x)
  # Notice that both Int32 and String respond_to `to_s`
  x.to_s.upcase
end

# If `ENV["FOO"]` is defined, use that, else `10`
foo = ENV["FOO"]? || 10

puts typeof(foo) # => (Int32 | String)
puts typeof(shout(foo)) # => String

空引用检查

nil 值由一个特殊类型表示,Nil,任何可能为 nil 的值都具有包含 Nil 的联合类型。

因此,编译器可以在编译时判断值是否为空。它强制执行对 nil 值的显式处理,有助于防止可怕的 十亿美元错误

foo = [nil, "hello world"].sample

# The type of `foo` is a union of `String` and `Nil``
puts typeof(foo) # => String | Nil

# This would be a type error:
# puts foo.upcase # Error: undefined method 'upcase' for Nil

# The condition excludes `Nil` and inside the branch `foo`'s type is `String`.
if foo
  puts typeof(foo) # => String
  puts foo.upcase
end

语法

Crystal 的语法深受 Ruby 的启发,因此阅读起来很自然,编写也很容易,并且对于经验丰富的 Ruby 开发人员来说,学习曲线更低。

class String
  def longest_repetition?
    max = chars
            .chunk(&.itself)
            .map(&.last)
            .max_by?(&.size)

    {max[0], max.size} if max
  end
end

puts "aaabb".longest_repetition? # => {'a', 3}

并发模型

Crystal 使用称为 fibers 的绿色线程来实现并发。 fibers 通过通道相互通信,而不必依赖共享内存或锁 (CSP)。

channel = Channel(Int32).new

3.times do |i|
  spawn do
    3.times do |j|
      sleep rand(100).milliseconds # add non-determinism for fun
      channel.send 10 * (i + 1) + j
    end
  end
end

9.times do
  puts channel.receive
end

C 绑定

Crystal 允许为 C 库定义绑定并调用它们。您可以轻松地使用现有的丰富的库生态系统。

当已经存在一些任务的良好库时,无需在 Crystal 中实现整个程序。

# Define the lib bindings and link info:
@[Link("m")]
lib LibM
  fun pow(x : LibC::Double, y : LibC::Double) : LibC::Double
end

# Call a C function like a Crystal method:
puts LibM.pow(2.0, 4.0) # => 16.0

# This example intentionally uses a simple standard C function to be succinct.
# Of course you could do *this specific* calculation in native Crystal as well:
# 2.0 ** 4.0 # => 16.0

Crystal 对元编程的答案是一个强大的宏系统,它涵盖了从基本模板和 AST 检查到类型检查和运行任意外部程序。

class Object
  def has_instance_var?(name) : Bool
    {{ @type.instance_vars.map &.name.stringify }}.includes? name
  end
end

class Person
  property name : String

  def initialize(@name)
  end
end

person = Person.new "John"
p! person.has_instance_var?("name") # => true
p! person.has_instance_var?("birthday") # => false

依赖关系

Crystal 库打包成 Shards,这是一个没有集中式仓库的分布式依赖管理工具。

它读取 shard.yml 中定义的依赖关系,并从它们的仓库中获取源代码。

name: my-first-crystal-app
version: 1.0.0
license: Apache-2.0

authors:
- Crys <[email protected]>

dependencies:
  mysql:
    github: crystal-lang/crystal-mysql
    version: ~>0.16.0

development_dependencies:
  ameba:
    github: crystal-ameba/ameba

新闻


赞助

通过 OpenCollective 在三个简单步骤内成为 Crystal 的赞助商

贡献
企业支持

赞助 Crystal 为您的品牌创造了一个绝佳的跳板

获得支持
雇用我们参与您的项目

您可以利用语言创建者本身的专业知识来指导您的实现。

雇用我们

顶级赞助商

成功案例