Ruby中的to_s与to_str(以及to_i/to_a/to_h与to_int/to_ary/to_hash)

q35jwt9p  于 5个月前  发布在  Ruby
关注(0)|答案(3)|浏览(63)

我正在学习Ruby,我看到了一些让我有点困惑的方法,特别是to_sto_str(同样,to_i/to_intto_a/to_ary,& to_h/to_hash)。我读到的解释是,(例如to_s)用于显式转换,而较长的形式用于隐式转换。
我真的不明白to_str实际上是如何使用的。除了String之外的东西会定义to_str吗?你能给予一个这个方法的实际应用吗?

8wtpewkr

8wtpewkr1#

首先要注意的是,所有这些都适用于Ruby中的每一对“短”(例如to_s/to_i/to_a/to_h)和“长”(例如to_str/to_int/to_ary/to_hash)强制转换方法(对于它们各自的类型),因为它们都具有相同的语义。
它们有不同的含义。你不应该实现to_str,除非你的对象像一个字符串,而不仅仅是一个字符串。唯一实现to_str的核心类是String本身。
来自 Programming Ruby(引用自this blog post,值得阅读):
[to_ito_s]不是特别严格:如果一个对象有某种合适的字符串表示,例如,它可能会有一个to_s方法.[to_intto_str]是严格的转换函数:只有当[你的]对象可以自然地在任何地方使用字符串或整数时,你才能实现它们。
来自Pickaxe的较早的Ruby文档是这样说的:
与几乎所有类都支持的to_s不同,to_str通常只由那些行为类似于字符串的类实现。
例如,除了String,Float和Numeric都实现了to_intto_i相当于to_str),因为它们都可以很容易地替换String(它们实际上都是数字)。除非你的类与String有类似的紧密关系,否则你不应该实现to_str

xpszyzbs

xpszyzbs2#

为了理解你是否应该使用/实现to_s/to_str,让我们看看一些例子。当这些方法失败时,考虑**是很有启发性的。

1.to_s              # returns "1"
Object.new.to_s     # returns "#<Object:0x4932990>"
1.to_str            # raises NoMethodError
Object.new.to_str   # raises NoMethodError

字符串
正如我们所看到的,to_s很乐意将任何对象转换为字符串。另一方面,to_str在其参数看起来不像字符串时引发错误
现在我们来看一下Array#join

[1,2].join(',')     # returns "1,2"
[1,2].join(3)       # fails, the argument does not look like a valid separator.


Array#join在连接数组中的项(无论它们实际是什么)之前将它们转换为字符串是很有用的,因此Array#join对它们调用to_s
然而,分隔符应该是一个字符串--有人调用[1,2].join(3)可能是犯了一个错误。这就是为什么Array#join在分隔符上调用to_str
同样的原则似乎也适用于其他方法。考虑哈希上的to_a/to_ary

{1 => 2}.to_a      # returns [[1, 2]], an array that describes the hash
{1 => 2}.to_ary    # fails, because a hash is not really an array.


总之,我是这样看的:

  • 调用to_s获取描述对象的字符串。
  • 调用to_str来验证一个对象是否真的像字符串一样。
  • 当你可以构建一个描述你的对象的字符串时,实现to_s
  • 当你对象可以完全像字符串一样运行时,实现to_str

我认为你可以自己实现to_str的一个例子是ColoredString类--一个带有颜色的字符串。如果你很清楚向join传递一个彩色逗号不是错误,应该得到"1,2"(即使这个字符串没有颜色),那么就在ColoredString上实现to_str

f1tvaqid

f1tvaqid3#

Zverok有一个很好的容易理解的关于何时使用什么的文章(用to_h和to_hash解释)。
它必须确定实现这些方法的Object是否可以转换为字符串-> use to_s
或者它是某种(增强的)字符串类型-> use to_str
我在gem 'configuration'GitHubConfiguration.rb)中的Configuration类的实践中看到了to_hash的有意义的用法。
它表示-正如其名称所示-提供的配置,实际上是一种散列(具有附加功能),而不是可转换为散列。

相关问题