在Ruby中,String()和#to_s之间有什么区别

Cli*_*chl 9 ruby coding-style

String(1.1) == (1.1).to_s    => true
String(1.1) === (1.1).to_s   => true
Run Code Online (Sandbox Code Playgroud)

这两种强制方法之间有区别吗?如果是这样,你能证明吗?

mat*_*att 14

方法文档String说:

通过调用其to_s方法将arg转换为String.

所以一般来说它们都是一样的,但也存在一些差异 - 尽管你不太可能真实地看到它们.String()检查其参数的类,如果它还没有,String则调用to_s它.to_s直接调用意味着无论如何调用该方法.

考虑班级:

class MyString < String
  def to_s
    "Overridden to_s method"
  end
end
Run Code Online (Sandbox Code Playgroud)

一个实例MyString已经是一个String对象,所以将它作为参数传递给String()它将不会做任何事情.to_s然而,召唤它将返回Overridden to_s method.

1.9.3p286 :010 > m = MyString.new 'my string'
 => "my string" 
1.9.3p286 :011 > o = String.new 'orig string'
 => "orig string" 
1.9.3p286 :012 > String o
 => "orig string" 
1.9.3p286 :013 > String m
 => "my string" 
1.9.3p286 :014 > o.to_s
 => "orig string" 
1.9.3p286 :015 > m.to_s
 => "Overridden to_s method" 
Run Code Online (Sandbox Code Playgroud)

你永远不可能需要重写to_s一个String像这样的子类,一般你可以把String()to_s一样的,但它可能是知道发生了什么事情有用.


Cli*_*chl 5

当它们失败时,它们会引发不同的异常:

bo = BasicObject.new

String(bo)
TypeError: can't convert BasicObject into String

bo.to_s
NoMethodError: undefined method `to_s' for #<BasicObject:0x0003efbfd79c10>
Run Code Online (Sandbox Code Playgroud)