Ruby 2.1冻结字符串
Ruby 2.1将有一个冻结的字符串,这样在解释器每次运行时就不会重新创建对象,即Ruby 2.1冻结字符串,ruby,string,ruby-2.1,Ruby,String,Ruby 2.1,Ruby 2.1将有一个冻结的字符串,这样在解释器每次运行时就不会重新创建对象,即 my_hash["abcd"f] = 123 为什么解释器不能自动检测到这个字符串不会改变,而只是自动冻结它 或者,在ruby 2.1之前,一旦解释器开始运行,任何代码如何更改这样的字符串?如果我们说“abcd”需要冻结,那么一定有办法改变它 --更新:上面的问题已经更新了,所以下面的注释有点尴尬,但是前面的代码示例没有那么好 --更新:Ruby密钥将自动冻结。 关于你的第一个问题: 因为解释器无法预见该字符串
my_hash["abcd"f] = 123
为什么解释器不能自动检测到这个字符串不会改变,而只是自动冻结它
或者,在ruby 2.1之前,一旦解释器开始运行,任何代码如何更改这样的字符串?如果我们说“abcd”需要冻结,那么一定有办法改变它
--更新:上面的问题已经更新了,所以下面的注释有点尴尬,但是前面的代码示例没有那么好
--更新:Ruby密钥将自动冻结。- 关于你的第一个问题: 因为解释器无法预见该字符串实例以后是否会被任何破坏性方法修改
- 关于第二个问题(在“或”之后):
通过
上的任何破坏性方法,如字符串
反向代码>,
,预结束
等concat
- 关于你的第一个问题: 因为解释器无法预见该字符串实例以后是否会被任何破坏性方法修改
- 关于第二个问题(在“或”之后):
通过
上的任何破坏性方法,如字符串
反向代码>,
,预结束
等concat
- Ruby是一种动态语言。没有静态编译,解释器很难提前知道谁将最终访问和修改变量
让我们看看下面的例子。您有一个
字符串
str = "foo"
然后在以后的代码中
str.upcase!
# => "FOO"
即使对于一个简单的解析器来说,这个例子也非常简单,因为它可以理解字符串发生了变化。但是,让我们添加一些更复杂的内容
str = "foo"
method = ["up", "case"]
str.send((method << "!").join)
# => "FOO"
str=“foo”
方法=[“up”,“case”]
str.send((方法“FOO”)
这将产生与以前完全相同的结果,但该方法不是在脚本中静态编码的,而是在运行时对字符串动态执行的计算结果
但是等等,让我们把它弄得更复杂
str = "foo"
method = [ARGV.first, "case"]
str.send((method << "!").join) if ARGC.to_i > 0
# => "FOO"
str=“foo”
方法=[ARGV.first,“case”]
str.send((方法0
#=>“FOO”
在本例中,假设我从命令行传递参数,将计算转换方法,然后将其应用于字符串
正如您所猜测的,在这两种情况下,知道str
将要更改的唯一方法是实际执行代码
这些例子也可以回答问题的第二部分
一旦解释器开始运行,任何代码怎么能更改这样的字符串呢?如果我们说“abcd”需要冻结,那么一定有办法更改它
作为旁注,我想指出,“冻结字符串文字”功能最近有所发展,现在足以将变量标记为冻结
在Ruby 2.1中,“str”.freeze
由编译器优化,在每次调用时返回一个共享的冻结字符串。最初实现了另一种“str”f语法,但后来又恢复了
Ruby是一种动态语言,没有静态编译,解释器很难提前知道谁将最终访问和修改变量 让我们看看下面的示例。您有一个
字符串
str = "foo"
然后在以后的代码中
str.upcase!
# => "FOO"
即使对于一个简单的解析器来说,这个例子也非常简单,因为它理解了字符串的变异
str = "foo"
method = ["up", "case"]
str.send((method << "!").join)
# => "FOO"
str=“foo”
方法=[“up”,“case”]
str.send((方法“FOO”)
这将产生与以前完全相同的结果,但该方法不是在脚本中静态编码的,而是在运行时对字符串动态执行的计算结果
但是等等,让我们把它弄得更复杂
str = "foo"
method = [ARGV.first, "case"]
str.send((method << "!").join) if ARGC.to_i > 0
# => "FOO"
str=“foo”
方法=[ARGV.first,“case”]
str.send((方法0
#=>“FOO”
在本例中,假设我从命令行传递参数,将计算转换方法,然后将其应用于字符串
正如您所猜测的,在这两种情况下,知道str
将要更改的唯一方法是实际执行代码
这些例子也可以回答问题的第二部分
一旦解释器开始运行,任何代码怎么能更改这样的字符串呢?如果我们说“abcd”需要冻结,那么一定有办法更改它
作为旁注,我想指出,“冻结字符串文字”功能最近有所发展,现在足以将变量标记为冻结
在Ruby 2.1中,“str”.freeze
由编译器优化,在每次调用时返回一个共享的冻结字符串。最初实现了另一种“str”f语法,但后来又恢复了
mydef.sub!('a','o')
如果字符串被自动冻结,将抛出一个不需要的运行时错误。这就是您的观点的一个例子吗?(这替换了前面一个措词不好的注释j。)我尝试了mydef.sub!('a',!')).mydef在下次通话时仍将返回'abcd'。我清理了@CarySwovelandI的措辞@sawa@Daniel-我的意思是,如果Ruby将def mydef()“abcd”end处理为def mydef()“abcd”。冻结end
,mydef.sub!(“a”,“o”)
=>运行时错误:无法修改冻结字符串(v2.0.0)(虽然mydef
将继续返回“abcd”)。因此我们不希望Ruby冻结字符串。我认为这是sawa的观点。mydef.sub!('a','o')
如果字符串被自动冻结,将抛出一个不必要的运行时错误。这就是您的观点的一个例子吗?(这取代了先前措辞拙劣的注释J。)我尝试了mydef.sub!('a','!')。mydef在下一个ca上仍将返回'abcd'