理解 byref、ref 和 & [英] Understanding byref, ref and &

查看:20
本文介绍了理解 byref、ref 和 &的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我开始明白 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:

  1. Ref 关键字:关键字 ref 用于从值创建对推断类型的该值的引用.所以

  1. 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 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 = new Ref(10) 其中 Ref 类型具有可变字段 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# 中的 outref 修饰符.请注意,您不能创建这种类型的局部变量.

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.

&operator 是一种创建值(指针)的方法,该值可以作为参数传递给需要 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 的示例之所以有效,是因为您正在向方法传递对局部可变变量的引用.通过引用,该方法可以更改存储在该变量中的值.

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 实例中的堆上的值,但您不再拥有对该对象的引用.

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)  

这是可行的,因为 aRef 类型的值,并且您将指向堆分配实例的指针传递给 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 和 &amp;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆