crystal-chinaChina
  • 本站源码
  • 注册
  • 登录
目录
  • 前言
  • 简介
  • 安装 ➤
    • 包管理
  • 写给 Rubyists ➤
    • 类型
    • 方法
    • 代码块
    • 杂项
    • 性能因素
    • 迁移 Ruby 代码到 Crystal
  • 基础知识
  • 交叉编译

基础知识一些基础知识的简单总结

创建于:2025年03月16日 最后编辑于: 2025年02月19日

本文部分内容直接翻译自官方语言简介

学习一门语言的第一件事情,就是打印 Hello World!, 虽然这在 Crystal 里实在有点无聊。

   1  
   2  puts "Hello Crystal!"
   3  

puts 是一个定义在顶级作用域的方法,可以直接被调用。名字是 PUT String 的简写,一个由双引号表示的字符串作为参数传递给给这个方法,puts 打印它标准输出(STDOUT)。

方法调用时的括号是可选的。


§ 本地变量

一个本地变量必须以 小写字母 或 underscore _ 开头(后者一般是保留做特殊用途的变量),由 A-Z, a-z, 0-9 以及 _ 组成

一个本地变量的类型在赋值时自动推断,这里使用 typeof 获取一个变量的类型,并使用 p! (用作调试目的打印对象内部形式的方法)打印出来

   1  
   2  message = "Hello Crystal!"
   3  
   4  p! typeof(message) # => String
   5  

变量可以被重新赋值,甚至是不同类型的值

   1  
   2  message = "Hello Crystal!"
   3  
   4  p! typeof(message) # => String
   5  
   6  message = 73
   7  
   8  p! typeof(message) # => Int32
   9  

§ 字符串

Crystal 中的字符串是由连续的 UTF-8 编码的 unicode 字符组成的,并且是不可变的。

空字符(null character, codepoint 0) 在 Crystal 的字符串中仅仅是一个普通字符,并不作为字符串的结尾标志,实际字符串大小,取决于字符串对象的 #size 方法返回值。

💡 小提示

和 Ruby 不同,单引号字符串,例如:‘Hello' 在 Crystal中是不合法的。

类似于 C,以及 Rust, Crystal 中的字符串必须使用双引号表示,例如:"Hello!"

单引号则表示 Char, 例如:'A'

字符串插值使用 #{}, 其中可以使用任何表达式,只要它响应 #to_s (在所有对象已经被定义)

   1  
   2  name = "Crystal"
   3  age = 12
   4  puts "Hello #{name}, Happy #{age}th anniversary!" # => "Hello Crystal, Happy 12th anniversary!"
   5  

转义字符使用反斜杠(backslash) \

   1  
   2  puts "I say: \"Hello World!\"\n\t!"
   3  
   4  # => I say: "Hello World!"
   5  #        !
   6  

为了避免不必要的转义,Crystal 支持使用 %(...) 形式定义字符串。

   1  
   2  puts %(I say: "Hello World!"\n\t!)
   3  
   4  # => I say: "Hello World!"
   5  #        !
   6  

直接使用 unicode 是支持的,下面的两行字符串输出结果相同:

   1  
   2  puts "Hello 🌐"
   3  puts "Hello \u{1F310}" # => Hello 🌐
   4  

String 类 提供了非常多有用的方法,例如:

   1  
   2  String#size		返回字符串大小
   3  String#empty?		字符串是否为空
   4  String#blank?		字符串是否空白(只有白空格whitespace 返回 true)
   5  String#includes?		子串匹配
   6  String#sub		字符串替换
   7  String#index		字符串对应字符索引
   8  String#[]			字符串切片,例如:"hello"[1..3] => ell
   9  ...
  10  

查阅 API 文档获取更多的帮助。

§ 方法

定义一个方法使用 def 关键字,后面跟括号以及参数,括号是可选的,但是建议总是添加。

调用传递参数的方法,括号也是可选的,通常只有在特定场景下,读起来像自然语言且更容易理解时才会省略括号。

💡 小提示

不同于 Ruby,Crystal 中调用一个方法并传递参数时,同一个实参既可以使用普通方式传递,也可以使用关键字参数方式调用

更多详情见 调用方法时传递关键字参数

方法参数允许指定默认值

   1  
   2  def say_hello(recipient = "World")
   3    puts "Hello #{recipient}!"
   4  end
   5  
   6  say_hello # => "Hello World!"
   7  

可以精确限制传入参数的类型。

   1  
   2  def say_hello(recipient : String) # => 限制参数类型必须是 String
   3    puts "Hello #{recipient}!"
   4  end
   5  
   6  say_hello 100 # => Error: expected argument #1 to 'say_hello' to be String, not Int32
   7  

以及精确限制返回值类型。

💡 小提示

可以在方法体(body)的任何地方通过 return ??? 语句提前返回方法,传递给 return 的参数将作为返回值。

return 没有任何参数将返回 nil

否则,方法体中的最后一个表达式将作为返回值。

   1  
   2  def say_hello(recipient : String) : String  # => 限制返回值类型必须是 String
   3    puts "Hello #{recipient}!"
   4  end
   5  
   6  say_hello "Crystal" # => Error: method ::say_hello must return String but it is returning Nil
   7  

更多有关方法签名的文档,参考 定义方法名同名的方法


§ 顶级作用域

不属于任何命名空间的类型,常量,宏以及方法, 属于顶级作用域。

定义在顶级作用域的表达式会被立即执行,而无需像很多其他语言一样,需要定义一个 main 函数。

   1  
   2  # Defines a method in the top-level scope
   3  def add(x, y)
   4    x + y
   5  end
   6  
   7  # Invokes the add method on the top-level scope
   8  add(1, 2) # => 3
   9  
💡 小提示

你总可以通过 :: 来引用顶级作用域中存在的定义, 甚至是定义在顶级作用域的方法。

   1  
   2  def hello
   3    "Hello in the top-level scope!"
   4  end
   5  
   6  A_CONSTANT = "::CONST"
   7  
   8  class A
   9    A_CONSTANT = "A::CONST"
  10    
  11    def hello
  12      ::hello # => 引用上面顶级作用域中定义的 hello method
  13    end
  14  
  15    def const
  16      ::A_CONSTANT
  17    end
  18  end
  19  
  20  a = A.new
  21  p! a.hello # => "Hello in the top-level scope!"
  22  p! a.const # => "::CONST"
  23  
💡 小提示

顶级作用域中定义的的变量是 local 的,在方法中无法被看到,这点和很多语言,例如,JavaScript, Python,BASH 不同!

   1  
   2  x = 1
   3  
   4  def add(y)
   5    x + y # error: undefined local variable or method 'x'
   6  end
   7  
   8  add(2)
   9  

§ 真值

类似于 Ruby, 除了 false 和 nil(代表没有值) 之外的所有值,甚至包含 0,都被认为是真(truthy)的。

此外,在和 C 进行交互时,Pointer(Void).null 也作为 falsey 值对待。

   1  
   2  message = "Hello World"
   3  
   4  if message.starts_with?("Hello")
   5    puts "Hello to you, too!"
   6  end
   7  

§ 数字类型

证书和浮点数的默认类型是 Int32 和 Float64

   1  
   2  x = 1000_000
   3  y = 100.0
   4  
   5  p! typeof(x) # => Int32
   6  p! typeof(y) # => Float64
   7  
   8  p! 100 == 100.0 # => true
   9  
  10  p! 1 + 1, # addition 加法
  11    1 - 1,  # subtraction 减法
  12    2 * 3,  # multiplication 乘法
  13    2 ** 4, # exponentiation 指数
  14    2 / 3,  # division 除法
  15    2 // 3, # floor division 整数除
  16    3 % 2,  # modulus 取模
  17    -1,     # negation (unary) 取负
  18    -5.abs,   # absolute value
  19    4.3.round, # round to nearest integer
  20    5.even?,   # odd/even check
  21    10.gcd(16) # greatest common divisor
  22    Math::PI   # Archimedes' constant (TAU / 2)
  23  
previous_page迁移 Ruby 代码到 Crystal

基础知识

next_page查找性能瓶颈 (WIP)
欢迎在评论区留下你的见解、问题或建议

正在预览...
正在读取评论...
Crystal Chinaadmin@crystal-china.org
githubx.comcrystal-lang