这个问题实际上在很大程度上取决于特定的语言,因为有些语言允许您明确定义何时希望通过值传递变量以及何时通过引用传递变量,而有些则对于不同类型的变量总是以相同的方式进行。
一种非常流行的行为类型是在简单的时候使用按值传递(默认情况下):如 int、string、long、float、double、bool 等。
让我们展示内存对理论语言的影响:
int $myVariable = 5;
此时您已经在内存中创建了一个变量,它采用存储整数所需的大小(假设为 32 位)。
现在你想把它传递给一个函数:
function someFunction(int parameter)
{
printOnScreen(parameter);
}
所以你的代码看起来像:
function someFunction(int $parameter)
{
printOnScreen($parameter);
}
int $myVariable = 5; //Position A
someFunction($myVariable); //Position B
...rest of the code //Position C
由于简单类型是按值传递的,因此值会在内存中复制到另一个存储位置 - 因此:
在位置 A 期间,您的内存被 ONE int(值为 5)占用;
在位置 B 期间,您的内存被两个整数(值为 5)占用,因为您的 $myVariable 被复制到内存中
在位置 C 期间,您再次占用了 ONE int(值为 5)的内存,因为第二个 int 已被销毁,因为它仅在执行函数时需要
这还有一些其他含义:对按值传递的变量的修改不会影响原始变量 - 例如:
function someFunction(int $parameter)
{
$parameter = $parameter + 1;
printOnScreen($parameter);
}
int $myVariable = 5; //Position A
someFunction($myVariable); //Position B
printOnScreen($myVariable); //Position C
在位置 A 期间,您将变量 $myVariable 下的值设置为 5。
在位置 B 期间,您将 BY VALUE 传递给一个函数,该函数将您传递的值加 1。然而,因为它是一个简单的类型,通过值传递,它实际上对一个 LOCAL 变量进行操作,一个变量的副本。因此位置 C 将再次只写 5(您的原始变量,因为它没有被修改)。
某些语言允许您使用特殊运算符明确并告知您要传递引用而不是值本身 - 例如&。因此,让我们再次遵循相同的示例,但带有我们想要引用的明确信息(在函数的参数中
- 注意&):
function someFunction(int &$parameter)
{
$parameter = $parameter + 1;
printOnScreen($parameter);
}
int $myVariable = 5; //Position A
someFunction($myVariable); //Position B
printOnScreen($myVariable); //Position C
这一次的操作和内存影响会有所不同。
在位置 A 期间,创建了一个 int(每个变量始终由两个元素组成:内存中的位置和一个指针,它是位置的标识符。为了便于处理,让我们说指针始终是一个字节)。因此,每当您创建一个变量时,您实际上会创建两件事:
- 在内存中为 VALUE 保留位置(在本例中为 32 位,因为它是一个 int)
- 指针(8 位 [1 字节])
现在在位置 B 期间,函数期望 A POINTER 指向内存位置。这意味着它将在本地为自己创建指针的副本(1 个字节),而不是将实际保留位置作为新指针将指向与原始位置相同的位置。这意味着在功能运行期间,您拥有:
两个指向内存中的 int 的指针
为 int 的 VALUE 保留一个位置
这两个指针都指向同一个 VALUE
这意味着对值的任何修改都会影响两者。
因此查看相同的示例位置 C 也不会打印出 6,因为在函数内部我们已将 SAME POINTER 下的值修改为 $myVariable。
对于复杂类型(对象),大多数编程环境中的默认操作是传递引用(指针)。
例如 - 如果你有一个班级:
class Person {
public string $name;
}
并创建它的一个实例并设置一个值:
$john = new Person();
$john->name = "John Malkovic";
然后将其传递给函数:
function printName(Person $instanceOfPerson)
{
printOnScreen($instanceOfPerson);
}
就内存而言,它将再次在内存(1 字节)中创建一个指向相同值的新指针。所以有这样的代码:
function printName(Person $instanceOfPerson)
{
printOnScreen($instanceOfPerson);
}
$john = new Person(); // position A
printName($john); // position B
...rest of the code // position C
在位置 A 期间,您有:1 个人(这意味着 1 个指针 [1 字节] 指向内存中的某个位置,该位置具有存储人员类对象的大小)
在位置 B 期间,您有:2 个指针 [2 个字节],但在内存中仍然有一个位置来存储类 person 的值 [instance] 的对象
在位置 C 期间,您再次遇到位置 A 的情况
我希望这可以为您阐明主题 - 通常还有更多内容要介绍,我上面提到的只是一般解释。