【问题标题】:How to do user input in Crystal如何在 Crystal 中进行用户输入
【发布时间】:2018-07-26 06:43:09
【问题描述】:
puts "Input a number"
A = gets.try(&.to_i) || 0
puts "Ok now another number"
B = gets.try(&.to_i) || 0

def main 
    puts "Value of multiplication is #{A} * #{B}, Which equals = #{A * B}"
    puts "Value of addition is #{A} + #{B}, Which equals = #{A + B}"
    puts "Value of division is #{A} / #{B}, Which equals = #{A / B}"
    puts "Value of minus is #{A} - #{B}, Which equals = #{A - B}"
    puts "Value of modulus is #{A} % #{B}, Which equals = #{A % B}"
end 

main

我想知道从 Crystal 中的整数获取用户输入的最简单方法是什么?类似于Ruby的gets.chomp.to_i

【问题讨论】:

    标签: crystal-lang


    【解决方案1】:

    要获得用户输入,您必须了解gets 的工作原理。当用户输入内容时它会返回一个String,或者当用户没有输入任何内容(例如用户按下ctrl+C)时返回nil

    如果你这样做,在 Ruby 中:

    x = gets.chomp.to_i
    

    然后运行它,但是按 ctrl+C 你会在屏幕上打印一个丑陋的异常。也许这是可以接受的,但 Crystal 不会让你轻易通过,因为 Crystal 是类型安全的,你将不得不处理这种情况。也许您想为用户打印一些好东西而不是异常?

    处理Nil的方法在这里解释:https://crystal-lang.org/api/0.25.1/Nil.html

    例如你可以这样做:

    a = gets
    if a # if a is a String
      a = a.chomp.to_i # turn it into an integer
    else
      exit # just silently quit the program
    end
    

    另一种方法是使用to_nil!,如果值为nil,则本质上会引发异常:

    a = gets.not_nil!.chomp.to_i
    

    这更类似于 Ruby,因为当用户使用 ctrl+C 退出时,控制台中会显示异常。 主要区别在于 Crystal 让您知道(通过 nil)这种可能性可能发生,并且您应该选择在这种情况下该怎么做。

    有更多方法可以处理这种情况(如其他 cmets 中建议的 try 解决方案),具体取决于您希望代码的简洁程度。

    更接近 Ruby 的最后一个替代方案是使用 read_line,如果没有输入,它会引发,所以你可以这样做:

    a = read_line.chomp.to_i
    

    (虽然在我现在的实验中它似乎没有提高,我不知道为什么,可能是一些错误......)

    【讨论】:

    • 感谢您的回答!希望现在有更多的初学者会在这里看到这个。
    【解决方案2】:

    这将做你想做的事情,这样程序就不会继续,直到用户给你一个有效的 int。如果您只想简单地抛出错误,则不需要循环或 try-catch 语句。

    while true
      puts "give me a valid int:"
      begin
        i = gets.not_nil!.to_i
        break
      rescue
        puts "that wasn't a valid int."
      end
    end
    puts "you gave me: #{i}"
    

    【讨论】:

    • 谢谢,这很清楚,我可以用它来做其他输入练习。 gets.not_nil!.to_i这部分对我想做的事情特别有用!
    【解决方案3】:

    这里有两种解决方法:

    粗略:

    print "Input a number: "
    a = gets
    print "now another number: "
    b = gets
    
    begin
      a = a.not_nil!.to_i
      b = b.not_nil!.to_i
      puts "Value of multiplication is #{a} * #{b}, Which equals = #{a * b}"
      puts "Value of addition is #{a} + #{b}, Which equals = #{a + b}"
      puts "Value of division is #{a} / #{b}, Which equals = #{a / b}"
      puts "Value of minus is #{a} - #{b}, Which equals = #{a - b}"
      puts "Value of modulus is #{a} % #{b}, Which equals = #{a % b}"
    rescue e : Exception
      puts sprintf "error: input a or b is invalid: a = %s, b = %s", a, b
    end
    

    正常方式:

    def input(input : String) : Int
      value = 0
      loop do
        print input
        begin
          a = gets
          value = a.to_s.to_i  # Force convert (String | Nil) to String then Int32.
          break
        rescue
          # do nothing
        end
      end
      value
    end
    
    a = input "Input a number: "
    b = input "now another number: "
    puts "Value of multiplication is #{a} * #{b}, Which equals = #{a * b}"
    puts "Value of addition is #{a} + #{b}, Which equals = #{a + b}"
    puts "Value of division is #{a} / #{b}, Which equals = #{a / b}"
    puts "Value of minus is #{a} - #{b}, Which equals = #{a - b}"
    puts "Value of modulus is #{a} % #{b}, Which equals = #{a % b}"
    

    【讨论】:

    猜你喜欢
    • 2022-01-27
    • 1970-01-01
    • 1970-01-01
    • 2012-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-02
    • 1970-01-01
    相关资源
    最近更新 更多