zoukankan      html  css  js  c++  java
  • crystal-lang入门(二)

    CONTROL FLOW

    Primitive Types

    Nil

    最简单的类型就是Nil,它只有一个值,意味数值不存在。

    是否还记得String#index 。它返回一个nil值如果子字符串不存在于检索的字符串。它没有index,所以index位置不存在。

     Bool

    bool类型只有两个可能的值false和true。代表了布尔代数和逻辑真值。

    布尔值对于管理程序中的控制流特别有用。

    Boolean Algebra

    下面这个例子展示了操作符根据布尔值执行布尔代数:

     
    a = true
    b = false
    
    p! a && b, # conjunction (AND)
       a || b, # disjunction (OR)
       !a,     # negation (NOT)
       a != b, # inequivalence (XOR)
       a == b  # equivalence

    Truthiness

    布尔代数不限制类型仅为布尔类型。所有值有一个潜在真值:nil,false。以及null指针是falsey的,其他任一值(包括0)是truthy。

    用"foo"和nil代替上例的true和false看看。

    a = "foo"
    b = nil
    
    p! a && b, # conjunction (AND)
       a || b, # disjunction (OR)
       !a,     # negation (NOT)
       a != b, # inequivalence (XOR)
       a == b  # equivalence

    AND和OR运算符返回与运算符真值匹配的第一个操作数。

    p! "foo" && nil,
       "foo" && false,
       false || "foo",
       "bar" || "foo"

    NOT, XOR,==总是返回一个布尔值 (truefalse)。

    Control Flow

    Conditionals

    message = "Hello World"
    
    if message.starts_with?("Hello")
      puts "Hello to you, too!"
    end

    条件子句把代码分支放在门后,这个门只符合条件才开放。

    最基本的形式包含了关键词if,其后跟着一个表达式作为条件语句。条件语句当表达式的返回值是truthy时才满足。所有后续的表达式都是分支的一部分直到由关键词end结束。

    按照惯例,我们将嵌套的分支缩进两个空格。

    上例打印message仅当它满足条件语句,Hello在字符串开头。

    从技术上讲,这个程序仍然以预定义的顺序运行。fixed message总是匹配并使条件为真。但是假设我们没有在源代码中定义message的值。它也可以来自用户输入,例如聊天客户端。

    如果message 有一个值但不是以Hello开始,那么程序会跳过条件分支并不打印任何东西。

    条件表达式可以更复杂。使用布尔代数,我们可以构造一个接受Hello或Hi的条件:

    message = "Hello World"
    
    if message.starts_with?("Hello") || message.starts_with?("Hi")
      puts "Hey there!"
    end

    让我们把条件转换一下,只打印message当字符串不是以Hello为开头。

    这只是与上一个示例的一个小偏差:我们可以使用否定运算符(!)把条件变成相反的表达式

    message = "Hello World"
    
    if !message.starts_with?("Hello")
      puts "I didn't understand that."
    end

    另一种方法是将if替换为关键字unless,它期望相反的真值。unless x相当于 if !x。

    message = "Hello World"
    
    unless message.starts_with?("Hello")
      puts "I didn't understand that."
    end

    让我们看一个使用String#index查找子字符串并突出显示其位置的示例。还记得如果找不到子字符串,它返回nil吗?那样的话,我们什么都不能显示。所以我们需要一个if子句,条件是检查index是否为nil。.nil?方法是完美的。 

    str = "Crystal is awesome"
    index = str.index("aw")
    
    if !index.nil?
      puts str
      puts "#{" " * index}^^"
    end

     编译器实际上强制您处理nil情况。尝试删除条件或将条件更改为true:将显示一个类型错误,并说明不能在该表达式中使用Nil值。在适当的条件下,编译器知道在分支内index不能为nil,它可以用作数字输入。

    if !index.nil?的缩写是if index,两者基本上是等价的。只有当您想区分一个falsy值是nil还是false时,才有区别,因为前者的条件匹配false,而后者则不匹配。

    Else

    message = "Hello World"
    
    if message.starts_with?("Hello")
      puts "Hello to you, too!"
    end
    
    if !message.starts_with?("Hello")
      puts "I didn't understand that."
    end

    让我们改进我们的程序,并在这两种情况下做出反应,不管消息是否满足条件。
    我们可以将其作为两个独立的条件,条件为否定:

    message = "Hello World"
    
    if message.starts_with?("Hello")
      puts "Hello to you, too!"
    else
      puts "I didn't understand that."
    end

    这是可行的,但有两个缺点:条件表达式message.starts_with?(“Hello”)计算两次,效率很低。后来,如果我们在一个地方更改了条件(可能也允许Hi),我们可能也会忘记更改另一个。
    条件函数可以有多个分支。另一个分支由关键字else表示。如果不满足条件,则执行。

    More branches

    我们的程序只对Hello做出反应,但我们需要更多的交互。让我们添加一个分支来响应Bye。我们可以在同一个条件中有不同条件的分支。它就像一个else和另一个合成的if。因此关键字是elsif:

    else分支仍然只在前面两个条件都不满足时执行。不过,它总是可以省略的。

    请注意,不同的分支是互斥的,条件从上到下求值。在上面的例子中,这并不重要,因为这两个条件不能同时为真(message不能以Hello和Bye开头)。但是,我们可以添加一个非独占的替代条件来证明这一点:

    message = "Bye World"
    
    if message.starts_with?("Hello")
      puts "Hello to you, too!"
    elsif message.starts_with?("Bye")
      puts "See you later!"
    else
      puts "I didn't understand that."
    end

    这两个从句的分支条件相同,但顺序不同,它们的行为也不同。第一个匹配条件选择执行哪个分支。

    message = "Hello Crystal"
    
    if message.starts_with?("Hello")
      puts "Hello to you, too!"
    elsif message.includes?("Crystal")
      puts "Shine bright like a crystal."
    end
    
    if message.includes?("Crystal")
      puts "Shine bright like a crystal."
    elsif message.starts_with?("Hello")
      puts "Hello to you, too!"
    end
    所望隔山海
  • 相关阅读:
    服务器切换
    闭包函数
    函数对象+嵌套
    lvs讲解
    了解python
    rang enumerate
    set-集合功能介绍
    元组-tuple功能介绍
    dict-字典功能介绍
    list-列表功能介绍
  • 原文地址:https://www.cnblogs.com/otakus/p/14641499.html
Copyright © 2011-2022 走看看