理解 byref、ref 和 &
嗯,我开始了解到 F# 能够管理引用(某种类似于 C++ 的引用)。这使得可以更改在函数中传递的参数值,并且还使程序员能够返回多个值。 然而,这是我需要知道的:
Ref 关键字:关键字
ref
用于从值创建对推断类型的值的引用。所以让 myref = ref 10
这意味着 F# 将创建一个
Ref
类型的对象,并将我的int 10
放在那里(在可变字段中)。好的。因此,我假设
ref
用于创建Ref<'a>
类型的实例。正确吗?访问值:为了访问存储在引用中的值,我可以这样做:
让 myref = ref 10 让 myval = myref.Value 让 myval2 = !myref
虽然
:=
运算符只是让我编辑值,如下所示:让 myref = ref 10 myref.Value <- 30 我的参考:= 40
所以
!
(Bang) 取消引用我的引用。然后:=
编辑它。我想这也是正确的。&操作员:这个操作员做什么?它是否应用于引用类型?不,我想它必须应用于可变值,这会返回什么?参考?地址?如果使用交互式:
让可变的mutvar = 10;; &a;;
最后一行抛出错误,因此我不明白
&
运算ByRef:
byref
怎么样?这对我来说非常重要,但我意识到我不明白。 据我所知,它用于有关参数传递的函数。当一个人希望可以编辑传递的值时,可以使用 byref (这有点违背函数式语言的哲学,但 f# 的作用远不止于此)。考虑以下因素:let myfunc (x: int byref) = x < - x + 10
这很奇怪。我知道,如果您有一个引用
let myref = ref 10
,然后执行以下操作来编辑值:myref <- 10
则会出现错误,因为它应该像这个:myref := 10
。然而,在该函数中,我可以使用<-
运算符编辑x
,这意味着x
不是引用,对吗?< /p>如果我假设 x 不是引用,那么我还假设在函数中,当在参数上使用 byref 时,该参数可以具有可变语法应用于.所以这只是一个语法问题,如果我假设这我没问题,而且事实上,一切正常(没有编译器错误)。但是,
x
是什么?调用函数:如何使用利用 byref 参数的函数?
涉及到
&
运算符,但是您能更好地解释一下吗?在本文中:MSDN 参数和参数提供了以下示例:< /p>类型增量器(z) = 成员 this.Increment(i : int byref) = i <- i + z 让增量器 = 新增量器(1) 让可变的 x = 10 // A:不推荐:实际上不增加变量。 (我:为什么?) 增量器.Increment(ref x) // 打印 10。 printfn "%d" x 让可变 y = 10 incrementor.Increment(&y) (*我:&它返回什么?*) // 打印 11。 printfn "%d" y 让 refInt = ref 10 incrementor.Increment(refInt) (* 为什么它在 A 中不起作用,但在这里却起作用? *) // 打印 11。 printfn "%d" !refInt
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 keyword: The keyword
ref
is used to create, from a value, a reference to that value of the inferred type. Solet myref = ref 10
This means that F# will create an object of type
Ref<int>
putting there (in the mutable field) myint 10
.OK. So I assume that
ref
is used to create instances of theRef<'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
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: 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
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 editx
using the<-
operator means thatx
is not a reference, right?If I assume that
x
is not a reference, then I assume also that, in functions, when usingbyref
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 isx
?Calling functions: How can I use a function utilizing byref parameters?
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Ref 关键字 是的,当您编写
let a = ref 10
时,您实际上是在编写let a = new Ref(10)
其中Ref
类型具有可变字段Value
。访问值
:=
和!
运算符只是书写的快捷方式:ByRef 是一种特殊类型,可以(合理地)仅在方法参数中使用。这意味着参数本质上应该是指向某个内存位置(分配在堆或堆栈上)的指针。它对应于 C# 中的
out
和ref
修饰符。请注意,您无法创建这种类型的局部变量。&运算符是一种创建值(指针)的方法,该值可以作为参数传递给需要
byref
类型的函数/方法。调用函数 使用
byref
的示例之所以有效,是因为您向该方法传递了对本地可变变量的引用。通过引用,该方法可以更改存储在该变量中的值。以下内容不起作用:
原因是您正在创建
Ref
的新实例,并将a
的值复制到该实例中。然后,Increment
方法会修改Ref
实例中存储在堆上的值,但您不再拥有对此对象的引用。这是可行的,因为
a
是Ref
类型的值,并且您将指向堆分配实例的指针传递给Increment
然后使用!a
从堆分配的引用单元中获取值。(您可以使用使用
ref
创建的值作为byref
的参数,因为编译器会专门处理这种情况 - 它将自动引用Value
字段因为这是一个有用的场景...)。Ref keyword Yes, when you write
let a = ref 10
you're essentially writinglet a = new Ref<int>(10)
where theRef<T>
type has a mutable fieldValue
.Access value The
:=
and!
operators are just shortcuts for writing: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
andref
modifiers in C#. Note that you cannot create local variable of this type.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.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.The following doesn't work:
The reason is that you're creating a new instance of
Ref<int>
and you're copying the value ofa
into this instance. TheIncrement
method then modifies the value stored on heap in the instance ofRef<int>
, but you don't have a reference to this object anymore.This works, because
a
is a value of typeRef<int>
and you're passing a pointer to the heap-allocated instance toIncrement
and then get the value from heap-allocated reference cell using!a
.(You can use values created using
ref
as arguments forbyref
because the compiler handles this case specially - it will automatically take reference of theValue
field because this is a useful scenario...).