一个菜鸟问题

悬赏:5 发布时间:2008-07-25 提问人:loamy (初级程序员)

irb(main):009:0> a="123"
=> "123"
irb(main):010:0> b=a
=> "123"
irb(main):011:0> b
=> "123"
irb(main):012:0> b[0]="4"
=> "4"
irb(main):013:0> b
=> "423"
irb(main):014:0> a
=> "423"
a怎么也会改变?
该问题已经关闭: 超过15天由系统自动关闭,悬赏平分给所有参与回答的会员

回答

ruby的String对象和Java不一样,Java String对象所有public方法调用都是不可变的,而ruby String的[]方法是可变的,上面例子其实在Java里面如果调用了String的private方法(通过反射),也会有类似的结果:

	public static void main(String[] args) {
		String a = "abc";
		String b = a;
		toUpperCase(b);
		System.out.println(b);
		System.out.println(a);
	}

	public static void toUpperCase(String orig) {
		try {
			Field stringValue = String.class.getDeclaredField("value");
			stringValue.setAccessible(true);
			stringValue.set(orig, orig.toUpperCase().toCharArray());
		} catch (Exception ex) {
		}
	}
Quake Wang (中级程序员) 2008-07-25
ruby中string是可变的,估计lz是受到java String影响

其实irb(main):012:0> b[0]="4"
=> "4"
irb(main):013:0> b
=> "423"

就可以看出string被修改了
火星叔叔马丁 (初级程序员) 2008-07-25
irb(main):001:0> a='123'
=> "123"
irb(main):002:0> b=a
=> "123"
irb(main):003:0> a.object_id
=> 23974310
irb(main):004:0> b.object_id
=> 23974310

由此可见,b=a是将'123'的引用传递给了b,所以修改b的内容时,a的内容也会跟着修改掉了。
phoenix520 (初级程序员) 2008-07-28
如果想要不改.

把 b=a 改为

b=a.clone
open2ye (中级程序员) 2008-08-07
b[0]="4"


这一句执行的是,将字符串"123"的第一个字符赋值为"4",

你可以试试:

b[1]="4"
b[2]="4"

puts b => "444"
zqjshiyingxiong (初级程序员) 2008-08-07