了解byref,ref和& [英] Understanding byref, ref and &
问题描述
好吧,我开始了解F#能够管理引用(某种C ++,例如引用)。这样就可以更改函数中传递的参数值,还可以使程序员返回多个值。
但是,这是我需要知道的:
Well, I came to understand that F# is able to manage references (some sort of C++ like references). This enables the possibilities to change value of parameters passed in functions and also enables the programmer to return more than a single value. However here's what I need to know:
-
Ref关键字:关键字
ref
用于从一个值创建对该推断类型的值的引用。因此
Ref keyword: The keyword
ref
is used to create, from a value, a reference to that value of the inferred type. So
let myref = ref 10
这意味着F#将创建 Ref< int>
类型的对象(在可变字段中)放置我的 int 10
。
This means that F# will create an object of type Ref<int>
putting there (in the mutable field) my int 10
.
确定。因此,我假设使用 ref
创建 Ref<’a>
类型的实例。
OK. So I assume that ref
is used to create instances of the Ref<'a>
type. Is it correct?
访问值:为了访问存储在引用中的值,我可以这样做:
Access value: In order to access a value stored in reference I can do this:
let myref = ref 10
let myval = myref.Value
let myval2 = !myref
虽然:=
运算符只是让我这样编辑值:
While the :=
operator just lets me edit the value like this:
let myref = ref 10
myref.Value <- 30
myref := 40
所以!
(Bang)取消引用了我的引用。然后:=
对其进行编辑。我想这也是正确的。
So !
(Bang) dereferences my reference. And :=
edit it. I suppose this is correct too.
&接线员:这个接线员做什么?是否将其应用于引用类型?不,我猜必须将其应用于可变值,这将返回什么?参考资料?地址?如果使用交互式:
The & operator: What does this operator do? Is it to be applied to a reference type? No, I guess it must be applied to a mutable value and this returns what? The reference? The address? If using interactive:
let mutable mutvar = 10;;
&a;;
最后一行抛出错误,所以我不理解&
运算符适用。
The last line throws an error so I do not understand what the &
operator is for.
ByRef: byref
怎么样?这对我来说很重要,但我知道我不明白。
我知道它在有关参数传递的函数中使用。一个人在希望传递的值可以被编辑时使用byref(这有点违背功能语言的理念,但f#不仅如此)。请考虑以下内容:
ByRef: What about byref
? That's very important to me, but I realize I do not understand it.
I understand it is used in function regarding parameter passing. One uses byref when he wants that the passed value can be edited (this is a bit against the functional languages' philosophy but f# is something more than that). Consider the following:
let myfunc (x: int byref) =
x <- x + 10
这很奇怪。我知道如果您有一个引用 let myref = ref 10
,然后执行此操作以编辑值: myref<-10
会出现错误,因为它应该是这样的: myref:= 10
。但是,在该函数中我可以使用<-运算符编辑
x
的事实意味着 x
不是引用,对吧?
This is strange. I know that if you have a reference let myref = ref 10
and then do this to edit the value: myref <- 10
it arises an error because it should be like this: myref := 10
. However, the fact that in that function I can edit x
using the <-
operator means that x
is not a reference, right?
如果我假设 x
不是引用,那么我还假设在函数中,当对参数使用 byref
时,该参数可以应用可变语法。因此,这只是语法问题,如果我认为这没问题,那么实际上一切正常(没有编译器错误)。但是,什么是 x
?
If I assume that x
is not a reference, then I assume also that, in functions, when using byref
on a parameter, that parameter can have the mutable syntax applied to. So it is just a matter of syntax, if I assume this I am OK, and, in fact, everything works (no compiler errors). However, what is x
?
调用函数:如何使用利用byref参数的函数?
Calling functions: How can I use a function utilizing byref parameters?
涉及到&
运算符,但是您能更好地解释一下吗?在本文中: MSDN参数和参数提供了以下示例:
The &
operator is involved but could you explain this better please? In this article: MSDN Parameters and Arguments the following example is provided:
type Incrementor(z) =
member this.Increment(i : int byref) =
i <- i + z
let incrementor = new Incrementor(1)
let mutable x = 10
// A: Not recommended: Does not actually increment the variable. (Me: why?)
incrementor.Increment(ref x)
// Prints 10.
printfn "%d" x
let mutable y = 10
incrementor.Increment(&y) (* Me: & what does it return? *)
// Prints 11.
printfn "%d" y
let refInt = ref 10
incrementor.Increment(refInt) (* Why does it not work in A, but here it does? *)
// Prints 11.
printfn "%d" !refInt
推荐答案
Ref关键字是,当您编写 let a = ref 10
时,您实际上就是在编写 let a =新的Ref< int>(10)
,其中 Ref< T>
类型具有可变字段 Value
。
Ref keyword Yes, when you write let a = ref 10
you're essentially writing let a = new Ref<int>(10)
where the Ref<T>
type has a mutable field Value
.
访问值 :=
和!
运算符只是编写的快捷方式:
Access value The :=
and !
operators are just shortcuts for writing:
a.Value <- 10 // same as writing: a := 10
a.Value // same as writing: !a
ByRef 是一种特殊类型,只能(合理地)在方法参数中使用。这意味着该参数本质上应该是指向某个内存位置(分配在堆或堆栈上)的指针。它对应于C#中的 out
和 ref
修饰符。请注意,您无法创建这种类型的局部变量。
ByRef is a special type that can be (reasonably) used only in method parameters. It means that the argument should be essentially a pointer to some memory location (allocated on heap or stack). It corresponds to out
and ref
modifiers in C#. Note that you cannot create local variable of this type.
&运算符是一种创建值(指针)的方法,该值可以作为参数传递给期望为 byref
类型的函数/方法。
The & operator is a way to create a value (a pointer) that can be passed as an argument to a function/method expecting a byref
type.
调用函数具有 byref
的示例有效,因为您正在传递方法a引用局部可变变量。通过引用,该方法可以更改存储在该变量中的值。
Calling functions the example with byref
works because you're passing the method a reference to a local mutable variable. Via the reference, the method can change the value stored in that variable.
以下操作无效:
let a = 10 // Note: You don't even need 'mutable' here
bar.Increment(ref a)
原因是您正在创建 Ref< int>
的新实例将 a
的值复制到此实例中。然后, Increment
方法修改 Ref< int>
实例中存储在堆上的值,但是您不这样做
The reason is that you're creating a new instance of Ref<int>
and you're copying the value of a
into this instance. The Increment
method then modifies the value stored on heap in the instance of Ref<int>
, but you don't have a reference to this object anymore.
let a = ref 10
bar.Increment(a)
这是可行的,因为 a
是类型 Ref< int>
,然后将指向堆分配实例的指针传递给 Increment
,然后从中获取值使用!a
进行堆分配的参考单元格。
This works, because a
is a value of type Ref<int>
and you're passing a pointer to the heap-allocated instance to Increment
and then get the value from heap-allocated reference cell using !a
.
(您可以使用使用创建的值ref
作为 byref
的参数,因为编译器专门处理这种情况-它会自动引用 Value
字段,因为这是一个有用的方案...)。
(You can use values created using ref
as arguments for byref
because the compiler handles this case specially - it will automatically take reference of the Value
field because this is a useful scenario...).
这篇关于了解byref,ref和&的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!