Ruby字符串插值中to_s方法的工作原理是什么
Ruby字符串插值的
to_s回退逻辑原理 核心规则:使用#{}做字符串插值时,解释器对to_s返回值有严格的类型校验,不会直接采纳非字符串类型的返回结果。
具体执行逻辑
插值语法的底层执行流程如下:
- 优先调用插值对象自定义的
to_s方法,拿到返回值 - 校验该返回值是否为严格的
String类实例,这个过程不会做任何隐式类型转换——哪怕返回值实现了to_str隐式字符串转换方法,只要不是String类型直接判定为无效 - 如果返回值校验通过,直接拼接进最终字符串;如果校验不通过,直接忽略自定义
to_s的返回结果,回退调用C层面实现的原生Object#to_s方法,生成#<类名:内存地址>格式的默认字符串,整个过程不会抛出类型错误。
现象验证
你可以通过简单代码确认自定义to_s实际是被执行了的,只是返回值因类型不符合要求没被采纳:
class A; end a = A.new def a.to_s puts "自定义to_s方法已触发" # 加打印确认方法执行 2 # 返回整数,非字符串类型 end puts "#{a}" =begin 输出顺序: 自定义to_s方法已触发 #<A:0x00007fbbc8110090> =end
易混淆的逻辑差异
注意不要把字符串插值的逻辑和puts方法的逻辑搞混:
puts调用对象to_s后如果拿到非字符串结果,会继续对这个结果递归调用to_s直到拿到字符串,所以上面的例子里直接执行puts a会输出2- 字符串插值不会做递归转换,只要第一次
to_s返回的不是合法字符串,直接回退原生实现,不会处理非字符串返回值。
内容的提问来源于stack exchange,提问作者user3517175
相关产品推荐
相关产品推荐

