And*_*dry 24 .net f# reference parameter-passing byref
好吧,我开始明白F#能够管理引用(某种类似C++的引用).这使得有可能改变函数中传递的参数值,并使程序员能够返回多个值.不过这是我需要知道的:
Ref关键字:该关键字ref用于从值创建对推断类型的值的引用.所以
let myref = ref 10
Run Code Online (Sandbox Code Playgroud)
这意味着F#将创建一个类型的对象Ref<int>(在可变字段中)我的int 10.
好.所以我假设它ref用于创建该Ref<'a>类型的实例.这是对的吗?
访问值:为了访问存储在引用中的值,我可以这样做:
let myref = ref 10
let myval = myref.Value
let myval2 = !myref
Run Code Online (Sandbox Code Playgroud)
虽然:=操作员只是让我编辑这样的值:
let myref = ref 10
myref.Value <- 30
myref := 40
Run Code Online (Sandbox Code Playgroud)
所以!(Bang)取消引用我的参考.并:=编辑它.我想这也是正确的.
&运营商:这家运营商做什么?它是否适用于参考类型?不,我想它必须应用于一个可变值,这会返回什么?参考资料?地址?如果使用交互式:
let mutable mutvar = 10;;
&a;;
Run Code Online (Sandbox Code Playgroud)
最后一行抛出错误,所以我不明白&操作符是什么.
ByRef:怎么样byref?这对我来说非常重要,但我意识到我不理解它.我知道它用于参数传递的功能.当他想要传递的值可以被编辑时,人们会使用byref(这有点违背了函数式语言的哲学,但f#不仅仅是这个).考虑以下:
let myfunc (x: int byref) =
x <- x + 10
Run Code Online (Sandbox Code Playgroud)
这很奇怪.我知道如果你有一个引用let myref = ref 10,然后执行此操作来编辑值:myref <- 10它会出现错误,因为它应该是这样的:myref := 10.但是,在该功能中,我可以x使用<-运算符进行编辑,这意味着它x不是参考,对吧?
如果我假设这x不是引用,那么我还假设,在函数中,当byref在参数上使用时,该参数可以应用可变语法.所以这只是一个语法问题,如果我假设我没事,事实上,一切正常(没有编译器错误).但是,是什么x?
调用函数:如何使用函数使用byref参数?
该&运营商参与,但你能解释这更好的吗?在本文中:MSDN参数和参数提供以下示例:
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
Run Code Online (Sandbox Code Playgroud)Tom*_*cek 29
Ref关键字是的,当你写的时候你let a = ref 10基本上写的let a = new Ref<int>(10)是Ref<T>类型有一个可变字段Value.
访问值的:=和!运营商是用来写字的只是快捷方式:
a.Value <- 10 // same as writing: a := 10
a.Value // same as writing: !a
Run Code Online (Sandbox Code Playgroud)
ByRef是一种特殊类型,可以(合理地)仅用于方法参数.这意味着参数本质上应该是指向某个内存位置的指针(在堆或堆栈上分配).它对应于C#中的out和ref修饰符.请注意,您无法创建此类型的本地变量.
&运算符是一种创建值(指针)的方法,该值可以作为参数传递给期望byref类型的函数/方法.
通过函数调用函数示例,byref因为您正在向方法传递对本地可变变量的引用.通过引用,该方法可以更改存储在该变量中的值.
以下不起作用:
let a = 10 // Note: You don't even need 'mutable' here
bar.Increment(ref a)
Run Code Online (Sandbox Code Playgroud)
原因是您正在创建一个新实例,Ref<int>并且您正在将该值复制a到此实例中.Increment然后,该方法修改实例中存储在堆上的值Ref<int>,但您不再具有对该对象的引用.
let a = ref 10
bar.Increment(a)
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为它a是一个类型的值,Ref<int>您将指向堆分配的实例的指针传递给Increment,然后使用堆分配的引用单元格获取值!a.
(您可以使用使用refas参数创建的值,byref因为编译器会特别处理这种情况 - 它会自动引用该Value字段,因为这是一个有用的场景......).