F#支持“切片表达式”,例如,对于传统的一维数组myArray
,允许使用myArray.[3 .. 5]
等表达式。根据例如F#4.0语言规范(第6.4.7节),这是通过在适当转换参数后调用GetSlice方法实现的。这也适用于多维数组。但是,我在定义在二维情况下实现它的接口时遇到了一些麻烦。
我所做的是以下内容。我已经定义了一个接口如下:
type IMatrix =
abstract member GetSlice : ?start1:int * ?end1:int * ?start2:int * ?end2:int -> IMatrix
abstract member GetSlice : idx1:int * ?end1:int * ?start2:int * ?end2:int -> IMatrix
abstract member GetSlice : ?start1:int * ?end1:int * idx2:int -> IMatrix
这是基于我从说明书第6.4.7节中理解的说明。我的想法是,当我有一个名为IMatrix
的{{1}}时,我应该可以写
matrix
并获取matrix.[1 .. 2, 3 .. 4]
类型的子矩阵。这个想法基本上是IMatrix
转换为1 .. 2
而Some 1, Some 2
被编译器转换为3 .. 4
,这四种选项类型被赋予四参数{ {1}}方法。
但是,当我在实践中尝试这个时,编译器会报告没有重载与方法'GetSlice'匹配的错误,特别是提到类型'int'与类型'int选项'不兼容。因此在我看来,编译器正确地推断切片概念应该转换为GetSlice调用,但不知何故,参数混淆了。
顺便说一下,如果我在实现一维切片时尝试这个问题,我会遇到同样的问题。一个IVector接口,或者在类而不是接口上尝试这个时。
我该如何解决这个问题?
答案 0 :(得分:5)
我认为编译器只需要将参数显式为int option
类型,而不是int
类型的可选参数。以下类型检查:
type IMatrix =
abstract member GetSlice :
start1:int option * end1:int option *
start2:int option * end2:int option -> IMatrix
abstract member GetSlice :
idx1:int *
start2:int option * end2:int option -> IMatrix
abstract member GetSlice :
start1:int option * end1:int option *
idx2:int -> IMatrix
let m : IMatrix = failwith "!"
m.[1 .. 2, 3 .. 4]
m.[1, 3 .. 4]
m.[1 .. 2, 3]