昨天我遇到了这个问题,并且想知道传值,传递参考和传递参考的关系是什么。他们都表现得怎么样?哪种编程语言使用哪种?
此外: 我偶尔也会听到其他术语,如传递指针,传递副本,传递对象......它们如何适应?
答案 0 :(得分:1)
这是一个虚构的术语,指的是实际上是按值传递的东西,但人们总是感到困惑,因为语言中唯一的值是引用(指向事物的指针)。许多现代语言以这种方式工作,包括Java(用于非原语),JavaScript,Python,Ruby,Scheme,Smalltalk等。
初学者总是在StackOverflow上询问有关为什么它不是通过引用传递的问题,因为他们不明白传递的是什么传递。因此,为了满足他们,一些人构成了一个他们也不理解的新术语,但使他们看起来像是学到了什么,而且听起来有点像传值和传递参考。
术语的使用在不同语言社区之间差异很大。例如,Java社区几乎总是将这种语义描述为值传递,而Python和Ruby社区很少将其描述为按值传递,即使它们在语义上是相同的。
答案 1 :(得分:0)
让我们从基础开始。你可能已经知道这个或者至少认为你这样做了。令人惊讶的是,很多人实际上都在滥用这些术语(这对于混淆肯定没有帮助)。
我现在还没有告诉你答案,而是用例子来解释。你会在以后看到原因。
想象一下,你正在尝试学习一门编程语言,而一位朋友告诉你,他知道一本关于这个主题的好书。您有两种选择:
案例1:如果你借阅他的书并在边缘做笔记(并添加一些书签,参考文献,图纸......),你的朋友以后也可以从这些笔记和书签中受益。分享是关怀。世界太棒了!
案例2:但另一方面,如果你的朋友有点整洁,或者非常珍惜他的书,他可能不会欣赏你的笔记,甚至更少偶尔的咖啡渍或你如何折叠书签的角落。你应该得到自己的书,每个人都可以按自己喜欢的方式愉快地对待他的书。世界太棒了!
这两种情况 - 你猜对了 - 就像传递引用和传值一样。 区别在于函数的调用者是否可以看到被调用者所做的更改。
让我们看一下代码示例。 假设您有以下代码段:
function largePrint(text):
text = makeUpperCase(text)
print(text)
myText = "Hello"
largePrint(myText)
print(myText)
然后用值传递语言运行它,输出将是
HELLO
Hello
而在传递参考语言中,输出将是
HELLO
HELLO
如果你通过引用传递变量" myText"由功能改变。如果您只是传递变量的值,则函数无法更改它。
如果你需要另一个例子,this一个使用网站的人得到了不少赞成。
好的,既然我们已经掌握了基础知识,那就让我们继续......
让我们再次使用我们的书籍例子。假设你已经决定从朋友那里借这本书,虽然你知道他有多喜欢他的书。让我们假设你 - 然后就是你的总klutz - 在它上面洒了一加仑咖啡。天啊... 不用担心,你的大脑启动并意识到你可以给你的朋友买一本新书。它处于如此良好的状态,甚至没有注意到!
这个故事与传递参考值有什么关系?
好吧,另一方面,想象一下你的朋友非常喜欢他的书,他并不想把它借给你。但他确实同意带这本书给你看。问题是,你仍然可以将一加仑咖啡洒在上面,但现在你不能再为他买一本新书了。他会注意到的!
虽然这可能听起来很可怕(并且可能让你大汗淋漓,好像你已经喝了那加仑咖啡一样)但实际上它很常见并且是一种非常好的方法来<打击>分享书籍来电功能。它有时被称为pass-reference-by-value。
代码示例如何运作?
在pass-reference-by-value函数中,我们的代码段的输出是
HELLO
Hello
就像传值的情况一样。但是如果我们稍微改变一下代码:
function largePrint(text):
text.toUpperCase()
print(text)
myText = "Hello"
largePrint(myText)
print(myText)
输出变为:
HELLO
HELLO
就像传递参考案例一样。原因与书中的例子相同:我们可以通过调用text.toUpperCase()(或通过在其上溢出咖啡)来更改变量(或书)。但是我们不能再改变变量引用的对象(text = makeUppercase(text)没有效果);换句话说,我们不能使用不同的书。
您可以获得自己的书籍,自己的变量副本以及原始所有者永远不会知道的任何内容。
您使用与朋友相同的书或与调用者相同的变量。如果您更改了变量,它将在您的函数之外更改。
你和朋友一样使用同一本书,但他并没有让它离开他的视线。您可以更改书籍但不能更换书籍。在变量术语中,这意味着您无法更改变量引用,但您可以更改变量引用的
。现在,当我向您展示以下Python代码时:
def appendSeven(list):
list.append(7)
def replaceWithNewList(list):
list = ["a", "b", "c"]
firstList = [1, 2, 3, 4, 5, 6]
print(firstList)
appendSeven(firstList)
print(firstList)
secondList = ["x", "y", "z"]
print(secondList)
replaceWithNewList(secondList)
print(secondList)
告诉你输出是这个
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6, 7]
['x', 'y', 'z']
['x', 'y', 'z']
你怎么说?
确实,你是对的! Python使用pass-reference-by-value! (Java和Ruby以及Scheme也是如此......)
这是非常困难的吗?没有。 那么为什么这么多人会被它迷惑呢? (我不会链接到关于&#34的所有其他问题;我如何通过Python中的引用传递变量&#34;或者#34; Java是否通过引用传递?&#34;等等......)
嗯,我看到了几个原因:
如果您认为我应该添加任何内容,请告知我们。如果我弄错了,请让我知道!
对于那些仍然没有足够的人:http://en.wikipedia.org/wiki/Evaluation_strategy