a=b=c=[0]
x=y=z=0 # 与统一赋值很像
同样语法暗藏着似乎相反的语义。不搞清楚,就会踩坑。
a=b=c=[0]
x=y=z=0 # 与统一赋值很像
同样语法暗藏着似乎相反的语义。不搞清楚,就会踩坑。
这不是坑,是feature。你除了C之外难道没写过点别的语言么…Java C# Python Ruby啥的都行
Julia的变量从来就不是值语义,变量是可以绑定到值的名字(引用),变量之间的赋值从来都是让它们指向同一个东西。
只不过0作为bits类型Int的实例,是immutable的,所以
x = 0 #x指向Int类型的对象Int(0)
y = x #y和x指向同一个东西
x = 1 #x指向另一个Int类型的对象Int(0)
y #还是0
你无法通过修改Int
对象来对y
施加影响。
对于immutable的东西,只要内容是一样的,它们就是一样的(in the sense that no program could
distinguish them),虽然immutable赋值的具体实现可能只是一个mov
指令
julia> 0===0
true
julia> struct S
x
end
julia> S(0)===S(0)
true
julia> mutable struct M
x
end
julia> M(0)===M(0)
false
但是,[0]是Array,Array是mutable类型,所以
x = [0]
y = x #x和y指向同一个Array对象,并不是复制
x[1] = 1
y #y[1] == 1
所以,还是那句话,多看文档……
这么说的话,Julia中的标识和值是分离的吗
本来抛砖引玉,结果又是半砣砖砸到我自己
谈语言本身,正如:“坑” 是指“面上看不见,藏在下面的”一样。解释只是附加说明而已。
按题目,意义何在?茴香豆的回吗?
避免冗余和歧义,也是语言所追求的。
BTW,除了C 还有perl
#!/usr/bin/perl
use strict;
use warnings;
my @a=(10,20,30);
my @b=@a;
$a[1]=5;
print “a=@a\nb=@b\n”;
#--------------
结果:
a=10 5 30
b=10 20 30
另外,与其它语言争议较多的“数组0,1开头问题”反倒是个嘘头,没有争议的价值。
我记得动态语言不能控制复制时是传值还是传引用,在c中数组的话是一个数组两个变量名,其实就是指向同一个地址,c++可以通过拷贝构造函数控制,其他语言我就不知道,大概就是语言特性吧
还是变量语义的问题,C/C++的普通变量是值语义的,变量表示的是内存位置,比如
int x = 0;
它表示一个自动变量,是左值,在生存期内拥有稳定的内存位置,可以被寻址。
对比Julia,
x = 0
这里的x
只是一个名字,当前绑定到了某个Int
对象上(甚至它自身都是没有类型的,有类型的是值),x
并不代表内存位置,因此你无法取地址,也不能作为ccall
的输出参数。
再看看C++的STL,它从行为上也是模拟了值语义,因此
vector<int> v = { 1,2,3 };
vector<int> v_copy = v; // 复制了一份,看起来和基本类型一样
vector<int>& v_ref = v; // 引用指向v
vector<int>* v_ptr = &v; //指针指向v
使用operator=
直接赋值,会发生对象复制。如果你需要引用语义,则需要使用“引用”(C++术语)或者“指针”来实现。对于指针而言,它自身也是值语义的普通变量,访问所指需要进行解引用。
语言的基本设计都是不一样的,因此看起来不一样的表达式具有不同的含义,使用之前必须想清楚。
避免冗余和歧义,也是语言所追求的。
完全没有歧义,只是你不熟。
如果你在Julia里需要v_copy
行为,那么需要显式进行复制:
a = [1,2,3]
b = copy(a)
我记得动态语言不能控制复制时是传值还是传引用
动态语言和传值传引用没有关系。你说的“复制”可能是指“=
”的含义,这个不同语言都有自己的约定。
例如C#
是静态类型语言(没错,静态类型系统和垃圾回收之间也没有任何联系),但是C#的class
类型表现为引用语义,基本变量和struct
类型表现为值语义。
在c中数组的话是一个数组两个变量名
这是啥?
那个,声明一个数组a,然后b=a,b和a都是这个数组的别名,这个意思
传值传引用好像体现在函数传参那一部分
int a[] = { 1,2,3 };
int* b = a;
你说这个吗?a
是一个int[3]
数组,而b
是一个int*
指针,赋值的时候发生了隐式类型转换,数组a
退化成了&a[0]
,即首元素指针。以上代码的效果是b
指向了a
的首地址。
两个数组之间是无法赋值的。
只是举个例子与上面的perl语句区别开来
你的意思是 “看起来一样的表达式具有不同的含义”吧?“使用之前必须想清楚”意思是避免歧义吧?
意思是不要认为看起来一样的东西能生搬硬套到其他语言里去
在一个语言内部没有歧义
所以题目问题是什么?
a=b=c=[0]
a[1]= 1
会修改 b, c
指向的内容
a = [1]
不会修改 b, c
看心情,你要他们分离的话就copy
你说的都没错。其实讨论点在值语义和引用语义的选择上。这应当在教程简介的特色中阐述的,但基本上都不在那个地方明确讲。
通俗一点,一个是给变量赋值;一个是给值取名。
这两个语义一个是为了避免引用管理繁琐和不经意的bug;一个是为了节约内存。一个趋向人性化,一个趋向机器化。
这两个语义又不是不能共存。。在julia中immutable的类型是值语义,其他类型是引用语义,这有什么歧义吗?
是个折衷方案。用的时候得考虑清楚。
所以你的意思是要么全都是值语义,要么全都是引用语义吗?
或者像cpp一样严格区分,*&用起来吗,抱歉你说了这么多我还是不明白你想表达的意思。