JDB*_*JDB 3 f# pattern-matching let-binding
我编写了一个函数,该函数将一个数组作为输入并返回一个大小相等的数组作为输出。例如:
myFunc [| "apple"; "orange"; "banana" |]
Run Code Online (Sandbox Code Playgroud)
> val it : (string * string) [] =
[|("red", "sphere"); ("orange", "sphere"); ("yellow", "oblong")|]
Run Code Online (Sandbox Code Playgroud)
现在,我想通过let绑定分配结果。例如:
let [|
( appleColor, appleShape );
( orangeColor, orangeShape );
( bananaColor, bananaShape )
|] =
myFunc [| "apple"; "orange"; "banana" |]
Run Code Online (Sandbox Code Playgroud)
哪个很棒...
> val orangeShape : string = "sphere"
> val orangeColor : string = "orange"
> val bananaShape : string = "oblong"
> val bananaColor : string = "yellow"
> val appleShape : string = "sphere"
> val appleColor : string = "red"
Run Code Online (Sandbox Code Playgroud)
...除了会产生警告:
warning FS0025: Incomplete pattern matches on this expression. For example, the value '[|_; _; _; _|]' may indicate a case not covered by the pattern(s).
Run Code Online (Sandbox Code Playgroud)
警告的来源和原因已经讨论过,我只是在寻找一种简洁的解决方法。这个函数调用发生在我函数的顶部附近,我不喜欢将整个函数体放在匹配中的想法:
let otherFunc =
match myFunc [| "apple"; "orange"; "banana" |] with
| [|
( appleColor, appleShape );
( orangeColor, orangeShape );
( bananaColor, bananaShape )
|] ->
// ... the rest of my function logic
| _ -> failwith "Something impossible just happened!"
Run Code Online (Sandbox Code Playgroud)
那只是难闻的气味。我也不喜欢忽略警告的想法-与我的更好判断背道而驰。我还有其他选择吗,还是我只需要找到一种完全不同的方法?
如果您希望这种调用模式很常见,那么一种可能是使包装器作用于您期望的元组的大小,例如
myFunc3 (in1,in2,in3) =
match myFunc [|in1;in2;in3|] with
[|out1;out2;out3|] -> out1, out2, out3
_ -> failwith "Internal error"
Run Code Online (Sandbox Code Playgroud)
等等。但是它所做的只是将丑陋的代码移到标准位置,而写出包装程序将很不方便。
我认为该API没有更好的选择,因为无法告诉编译器myFunc总是返回与传递的元素数量相同的元素。
另一种选择是myFunc用一个IDisposable类代替:
type MyClass() =
let expensiveResource = ...
member this.MyFunc(v) = ...calculate something with v using expensiveResource
interface IDisposable with
override this.Dispose() = // cleanup resource
Run Code Online (Sandbox Code Playgroud)
然后像这样在块中使用它
use myClass = new MyClass()
let appleColor, appleShape = myClass.MyFunc(apple)
...
Run Code Online (Sandbox Code Playgroud)