如何在Crystal中进行用户输入

7
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

3个回答

7
为了获取用户输入,您需要了解如何使用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)告诉您可能发生这种情况,并且您应该在这种情况下选择要执行的操作。
有更多方法来处理此情况(例如其他评论中提出的try解决方案),具体取决于您希望代码有多简练。
最后一种更接近Ruby的替代方法是使用read_line,如果没有输入,则会引发异常,因此您只需执行以下操作:
a = read_line.chomp.to_i

(虽然在我的实验中现在似乎没有增加,但我不知道为什么,可能是某些错误...)


感谢您的回答!希望更多的初学者现在能看到这个问题。 - learncodes123

3
这会按照您的要求实现功能,直到用户输入有效的整数为止程序才会继续运行。如果您只想抛出错误,则不需要循环或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 这部分对我尝试做的事情特别有用! - learncodes123

1
这里有两种解决方法:
粗略的方法:
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}"

1
跟随这些例子,逐步学习:https://github.com/askn/crystal-by-example - icyleaf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接