在C#中,我可以为T类型的通用阵列像这样定义一个扩展方法:如何在F#中定义T []的类型扩展?
,但对我的生活我无法弄清楚如何做到在F#一样!我试过type 'a array with
,type array<'a> with
和type 'a[] with
,编译器对其中的任何一个都不满意。
任何人都可以告诉我什么是在F#中这样做的权利?
当然,我可以通过掩盖Array模块来做到这一点,并很容易地添加一个功能,但我真的想知道如何做到这一点,作为扩展方法!
在C#中,我可以为T类型的通用阵列像这样定义一个扩展方法:如何在F#中定义T []的类型扩展?
,但对我的生活我无法弄清楚如何做到在F#一样!我试过type 'a array with
,type array<'a> with
和type 'a[] with
,编译器对其中的任何一个都不满意。
任何人都可以告诉我什么是在F#中这样做的权利?
当然,我可以通过掩盖Array模块来做到这一点,并很容易地添加一个功能,但我真的想知道如何做到这一点,作为扩展方法!
你必须使用“反引号标记”写数组类型 - 这样的:
type 'a ``[]`` with
member x.GetOrDefault(n) =
if x.Length > n then x.[n]
else Unchecked.defaultof<'a>
let arr = [|1; 2; 3|]
arr.GetOrDefault(1) //2
arr.GetOrDefault(4) //0
编辑:语法type ``[]``<'a> with ...
似乎也被允许。在F#源文件(prim-types-prelude.fs)中,你可以找到如下定义:
type ``[]``<'T> = (# "!0[]" #)
好问题。我无法弄清楚如何延长'T[]
但你可以采取的事实,即阵列实现IList<_>
做:
type System.Collections.Generic.IList<'T> with
member x.GetOrDefault(n) =
if x.Count > n then x.[n]
else Unchecked.defaultof<'T>
let arr = [|1; 2; 3|]
arr.GetOrDefault(1) //2
arr.GetOrDefault(4) //0
我很确定F#中没有合法的语法来向数组类型添加扩展成员,所以这可能是最好的选择我不能想到任何缺点,除了这种方法也出现在任何其他IList类型中)。 – Brian 2012-08-06 21:36:47
@丹尼尔 - 圣洁的废话,你是对的! 'T []确实实施IList <'T>!我不知道!不知道这对我来说是否合理,但是一个数组需要连续的内存块,对吗?因此每次添加操作都必须重新分配给整个新阵列,这在我看来应该是你应该劝阻并鼓励使用List
'IList <_>'的变异成员,'Add' /'Remove'等,抛出'NotSupportedException'。尝试:'([| 1 |]:> System.Collections.Generic.IList <_>).Add(2)' – Daniel 2012-08-06 21:44:33
什么是“为我的生活”意味着:)? – Omu 2012-08-06 21:35:21
扩展'System.Array'是我的第一个想法,但需要一个类型参数和强制转换,除非你可以使用'obj'。 – Daniel 2012-08-06 21:39:37
@Chuck Norris - 意思是'我不能...甚至在我非常努力地尝试' – theburningmonk 2012-08-06 21:42:54