我正在尝试使用Ruby函数打印基本三角形图案,该函数仅接受n
的正奇数def triangle(n, chars)
puts "#{n} must be odd and positive" if n % 2 == 0 || n < 0 else (n + 1).times { |i| puts chars * i }
end
问题是这个函数不仅接受奇数而且接受正数n。
triangle(3, '#')
会打印
#
##
###
但是'triangle(4,'#')'也可以正常使用
#
##
###
####
似乎我的如果语句无法正常工作,我收到警告else without rescue is useless
。为什么以及如何解决这个问题?
答案 0 :(得分:5)
Ruby将您的代码解释为两个单独的语句。
puts "#{n} must be odd and positive" if n % 2 == 0 || n < 0
else (n + 1).times { |i| puts chars * i }
else
与if
无关。我猜想,Ruby在绝望中将其解释为begin/rescue/else
condition的一部分。为什么它不是语法错误,我不知道,但它将其解释为没有begin
块,这在技术上是成功的&#34;成功的&#34;所以else
总是运行。
do this if that
等条件语句仅适用于涵盖简单语句的简单条件。试图楔入其他条件是正确的。相反,使用正常情况。
def triangle(n, chars)
if n % 2 == 0 || n < 0
puts "#{n} must be odd and positive"
else
(n + 1).times { |i| puts chars * i }
end
end
通常,请立即完全避免else
处理错误情况。它避免了将大部分函数嵌套在else
块中。这对于更长时间的功能更为重要,但这是一个很好的习惯。
def triangle(n, chars)
if n % 2 == 0 || n < 0
puts "#{n} must be odd and positive"
return nil
end
(n + 1).times { |i| puts chars * i }
end
最后,应该使用异常处理错误,而不是打印错误消息。调用者可以捕获并处理异常,打印的错误消息很难捕获并冒泡到用户。如果不处理例外,则停止该计划;如果用户忘记处理错误,程序将停止并且他们知道要修复它。打印的错误消息只是让程序向前推进,可以忽略,导致进一步的问题。
也可以对异常进行分类,允许调用者确定发生了什么类型的错误并采取适当的行动。
def triangle(n, chars)
if n % 2 == 0 || n < 0
raise ArgumentError, "#{n} must be odd and positive"
end
(n + 1).times { |i| puts chars * i }
end
答案 1 :(得分:2)
问题似乎是流量控制与输出的逻辑混淆。我想这会做你想做的事:
def triangle(n, chars)
if (n % 2 == 0) || (n < 0)
puts "#{n} must be odd and positive"
else
(n + 1).times { |i| puts chars * i }
end
end
答案 2 :(得分:0)
作为一个更优雅的实现,让我们更进一步,处理意外的参数
def triangle(n, chars='#')
raise(ArgumentError, "{n} must be odd and positive") unless n.to_i.odd? && n.to_i > 0
1.upto(n.to_i) { |i| chars.to_s * i}
end
现在,这将处理响应n
的任何to_i
和响应chars
的任何to_s
。例如&#39; 13&#39;,[&#39; x&#39;,&#39; x&#39;,1]仍然是有效的参数,即使它们形成一个奇怪的三角形。
Ruby以这种方式非常支持duck typing,它使你的代码更少于特定于类型。