if ( item::class == RPG::Weapon )
print "yup"
end
case item::class
when RPG::Item
type = 0
when RPG::Weapon
type = 1
when RPG::Armor
type = 2
else
type = 10
end
我是Ruby的新手。 if语句运行正常并打印“是”,但case语句不能正常工作并将类型设置为10.我是否对某些事情视而不见?
答案 0 :(得分:2)
Module#===
测试参数是否为self
的实例。除了Class
之外,item.class
永远不会是任何事件的实例,特别是,它永远不会是RPG::Weapon
或RPG::Armor
的实例,因此when
都不会} branches将永远匹配,您将始终获得else
分支。
顺便说一句:使用名称空间解析运算符::
进行邮件发送而不是邮件发送运算符.
非常非惯用且令人困惑(并且赢了&#39 ; t适用于名称以大写字符开头的方法。事实上,我相信matz认为这个功能在Ruby中添加了一个错误。
另请注意,case
是一个表达式,事实上,Ruby中的所有都是表达式。
我会按如下方式编写代码:
type = case item
when RPG::Item
0
when RPG::Weapon
1
when RPG::Armor
2
else
10
end
然而,一般来说,条件是代码气味。 Ruby是一种面向对象的语言,多态性(即基于self
类型的方法调度)是all the conditional you need!实际上,在这个例子中,您是手动检查item
的类以确定其类型,但完全无论如何,调度的方法是什么!就个人而言,我会refactor这样的代码:
class RPG::Item
def type
0
end
end
class RPG::Weapon
def type
1
end
end
class RPG::Armor
def type
2
end
end
class RPG::Object # or whatever your baseclass is
def type
10
end
end
现在,当您添加新类型的游戏对象时,您不必通过向case
表达式添加新分支来修改现有代码。您只需添加新类,无需修改任何现有代码。
答案 1 :(得分:0)
只需case item
即可 - 无需case item::class
。
Ruby中的案例匹配是通过模糊匹配(===
)算法完成的,该算法并不需要这样的特定条款。