首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >电机计算

电机计算
EN

Code Review用户
提问于 2014-11-18 13:12:03
回答 2查看 564关注 0票数 5

ElectricalEngine类响应horsepower消息。因为效率是以百分比计算的,程序员可以错误地用整数而不是浮点数来初始化它。

代码语言:javascript
复制
class ElectricalEngine
  attr_reader :volts, :current, :efficiency

  def initialize(volts, current, efficiency)
    @volts, @current, @efficiency = volts, current, efficiency
  end

  HP_IN_WATTS = 746
  def horsepower
    (volts * current * efficiency) / HP_IN_WATTS
  end
end

puts ElectricalEngine.new(240, 90, .6).horsepower # correct
puts ElectricalEngine.new(240, 90, 60).horsepower # buggy

你将如何处理这种情况?

  1. 什么都不做。程序员有责任知道正确的数据类型。
  2. efficiency重命名为efficiency_as_float以使其更清晰。
  3. efficiency重命名为efficiency_as_percent,并调整horsepower的S计算。
  4. 编写一个自定义的efficiency方法来检查数据类型并进行相应的转换。
  5. 检查efficiency类型,如果它不是浮点数,则引发错误。
  6. 其他

解决方案四可能是这样的。当然,这种转换也可以在initialize方法中进行,但我认为这更简洁。

代码语言:javascript
复制
def horsepower
  (volts * current * efficiency_as_float) / HP_IN_WATTS
end

def efficiency_as_float
  if efficiency.is_a?(Integer) # what if 1 is passed in instead of 1.0?
    efficiency / 100.to_f
  else
    efficiency
  end
end

解决方案5如下所示:

代码语言:javascript
复制
def initialize(volts, current, efficiency)
  raise "Efficiency must be a float" unless efficiency.is_a?(Float)
  @volts, @current, @efficiency = volts, current, efficiency
end

ElectricalEngine是否有责任转换不正确的数据类型?

EN

回答 2

Code Review用户

回答已采纳

发布于 2014-11-18 14:08:24

我想选择#1:什么都不做(除了,正如m_x所说,使用to_f)。但是,如果你真的,真的想做些什么,选择第5条:引发一个错误。具体来说,我建议使用一条有用的消息来引发RangeError

代码语言:javascript
复制
raise RangeError, "efficiency must be between 0 and 1" unless (0..1).cover?(efficiency.to_f)

至于这一点:

因为效率是以百分比计算的,程序员可以错误地用整数而不是浮点数来初始化它。

是的,这是有可能发生的(我自己也犯过这样的错误),但使用0..1浮点数是更常见的方法(在我的经验中)。通常只有电子表格处理百分比为0..100;在大多数编程(和数学)上下文中,“百分比”意味着大约0..1数字。因此,将其称为efficiency_as_percent可能会产生相反的效果:在需要int的地方传递0..1浮点数。

无论哪种方式,效率并不是特定的百分比(尽管您可能会将其作为百分比);它只是一个比率。一个因素。因此,浮动更有意义,因为它们允许您设置比0..100更精确的值。

当然,对于所有这些,您必须有点务实,这样才不会在动态类型的语言中实现严格的类型。例如,您还可以检查voltscurrent --例如,它们可能不应该是负的。但很快就变成了一个令人头痛的问题。

你也可能会问,“如果我想计算一个超统一引擎的马力呢?”如果efficiency不能超过1.0,你就不能。但从某种意义上说,这只是代数。你有一个公式,你可以插上你想要的任何东西。插入某些值是否有意义并不会改变数学。从实际的角度来看,200%的效率引擎当然是不可能的,但是你仍然可以把数学做得很好。见鬼,即使是一个完美的,100%效率的引擎也是不可能的。所以你应该只允许0.1(半开放范围)吗?如果您不允许1.0本身,那么您允许的值有多近? 0.9? 0.99999?

同样,零效率引擎听起来像是一个错误,那么你也应该指出这一点吗?等等等等..。

无论如何,我可以检查efficiency,但我自己也不会为此烦恼。让程序员来做正确的事情或者承担后果。垃圾进入,垃圾输出。

票数 6
EN

Code Review用户

发布于 2014-11-18 13:44:52

我的两分钱:用鸭子打字。

代码语言:javascript
复制
@efficiency = efficiency.to_f

..。如果它像浮子一样嘎嘎作响,那么它就是浮子。这样就可以利用红宝石的威望来达到以下目的:

代码语言:javascript
复制
class EfficiencyProfile 
  def initialize(some_data, value)
    @data = some_data
    @efficiency_value = some_value 
  end

  def to_f 
    @efficiency_value.to_f
  end 
end 

e = EfficiencyProfile.new(some_big_chunk_of_data_about_engine_performance, 42)
ElectricalEngine.new(1,2,e) # would work without a complain

动态输入当然是危险的,但是如果您想从中受益,就必须接受它。

显式检查类型是一个半自动的解决方案,因为:

  • 它很麻烦,而且您永远不会像C编译器那样擅长它。
  • 它将完全消除动态类型的唯一好处:灵活性。
票数 6
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/70175

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档