Julia中如何区分按引用与按值传递对象?求示例
Great question! Let's break this down clearly, since Julia's "pass-by-sharing" can feel a bit nuanced compared to the strict "pass-by-value" or "pass-by-reference" models you might encounter in other languages.
Core Concept: Pass-by-Sharing in Julia
As you noted, Julia uses pass-by-sharing: when you pass a value to a function, it doesn't create a copy—instead, the function gets a new variable binding that points to the exact same value as the original. The key difference in behavior comes down to whether that value is mutable or immutable:
- For immutable types (like
Int,Float64,String,Tuple), you can't modify the value itself. Any "change" to the function parameter just creates a new value and rebinds the parameter variable, leaving the original value untouched. This behaves exactly like pass-by-value. - For mutable types (like
Array,Dict, or custommutable structs), you can modify the internal state of the value. Since both the original variable and the function parameter point to the same object, these changes are visible to the caller. This behaves exactly like pass-by-reference.
Example: Same Function, Two "Pass Styles"
Let's create a single function that handles both immutable and mutable inputs, then test it to see the difference in behavior.
Step 1: Define the function
function modify_input(x) if x isa Int # For immutable Int: this creates a new value, rebinds the local x x += 10 println("Inside function (Int): x = $x") elseif x isa Array # For mutable Array: this modifies the existing array's contents x[1] += 10 println("Inside function (Array): x = $x") end return x end
Step 2: Test with an immutable type (pass-by-value behavior)
When we pass an Int (immutable), the function's changes don't affect the original variable:
original_int = 5 println("Before function call: original_int = $original_int") modify_input(original_int) println("After function call: original_int = $original_int")
Output:
Before function call: original_int = 5 Inside function (Int): x = 15 After function call: original_int = 5
Why? The x += 10 line creates a new Int value (15) and assigns it to the local x variable in the function. The original original_int still points to the original 5—no changes to the original value are possible because Int is immutable.
Step 3: Test with a mutable type (pass-by-reference behavior)
When we pass an Array (mutable), the function's changes to the array's contents are visible outside the function:
original_array = [5] println("Before function call: original_array = $original_array") modify_input(original_array) println("After function call: original_array = $original_array")
Output:
Before function call: original_array = [5] Inside function (Array): x = [15] After function call: original_array = [15]
Why? The x[1] +=10 line modifies the internal state of the array that both original_array and the function's x parameter point to. Since arrays are mutable, this change affects all references to the same array object.
How to Explicitly "Choose" Pass Style
- Want pass-by-value behavior: Use any immutable type, or explicitly create a copy of a mutable type before passing it (e.g.,
modify_input(copy(original_array))—this way changes to the copy won't affect the original). - Want pass-by-reference behavior: Use a mutable type (array, dict, mutable struct), or wrap an immutable value in a mutable container if needed. For example:
This will outputmutable struct WrappedInt value::Int end function modify_wrapped(w::WrappedInt) w.value += 10 println("Inside function: w.value = $(w.value)") end wrapped = WrappedInt(5) println("Before: wrapped.value = $(wrapped.value)") modify_wrapped(wrapped) println("After: wrapped.value = $(wrapped.value)")15after the function call, since we're modifying the mutable struct's internal state.
内容的提问来源于stack exchange,提问作者logankilpatrick

