我试图弄清楚如何处理模式匹配的情况,它根据匹配返回不同的类型,我知道它必须为每个分支返回相同的类型,所以我不知道处理这种情况的"正确"方式是什么是:
我尝试在下面做一个我的困惑的例子,paintArr是一个数组,代表一个可以包含一些颜色或一个空槽的托盘.
paintArr.[i,j] .color属于Color选项,包含黑色和白色.
每个插槽的模式匹配应决定颜色是黑色还是白色,并将其索引添加到适当的阵列.
let sort (paintArr: Pallete) =
let black = [||]
let white = [||]
for i = 0 to 5 do
for j = 0 to 5 do
match ((Option.get (paintArr.[i,j])).color) with
| White -> Array.append white paintArr.[i,j]
| Black -> Array.append black paintArr.[i,j]
| None -> "not sure what to do here"
(black, white)
Run Code Online (Sandbox Code Playgroud)
基本上,我认为我的问题归结为:你如何处理这样的情况,在某些情况下我会得到一个匹配,要求我什么也不做,或者可能只是与其他情况不同的东西?
序言:很明显,你对F#缺乏经验.如果这是真的,我建议你先读一些书或一套教程(我总是推荐https://fsharpforfunandprofit.com/).您正在尝试使用比完整初学者应该处理的代码更复杂的代码.
首先,请注意,Array.append不会"更改"("更新","修改")数组,而是返回一个新数组 - 您给它的原始数组和新元素的串联.有了这些知识,很容易看出你的Array.append电话是无用的:它们会返回一些东西,但你只是立即扔掉它.
从上下文中,我了解到你真正想要做的是用它的扩展版本替换有问题的数组.为此,您需要声明您的数组mutable,然后使用"破坏性更新"运算符<-:
black <- Array.append black paintArr.[i,j]
Run Code Online (Sandbox Code Playgroud)
<-F#中的破坏性更新运算符=与C语言中的赋值语句等效.
现在,如果您使用这样的破坏性更新运算符,则此类表达式的结果类型将为unit- 空类型,用于表示"无值".这种类型只有一个值,它被写成两个括号,它们之间没有任何内容.例如:
> let x = ()
val x : unit = ()
Run Code Online (Sandbox Code Playgroud)
因此,为了实现"来自所有分支的相同类型"规则,您可以让第三个分支只返回一个unit值,而不调用任何函数:
| None -> ()
Run Code Online (Sandbox Code Playgroud)
将以上所有内容应用到您的代码中,我们得到:
let sort (paintArr: Pallete) =
let mutable black = [||]
let mutable white = [||]
for i = 0 to 5 do
match ((Option.get (paintArr.[i,j])).color) with
| White -> white <- Array.append white paintArr.[i,j]
| Black -> black <- Array.append black paintArr.[i,j]
| None -> ()
(black, white)
Run Code Online (Sandbox Code Playgroud)
但请注意,这仍然无法编译,因为其中还有其他错误.首先,Option.get只有当值paintArr.[i,j].color是一个Some值时才会起作用,但是当它出现时会崩溃None.其次,即使这个功能成功,它也会返回一种颜色,但是你会尝试将它与None颜色进行比较.这将产生编译时错误.
在这一点上推断你真正想做的事情有点难,但我会试着猜测.我将猜测这paintArr.[i,j].color是类型的Color option,其中,Color是包括枚举White,Black和一些其他的颜色.
如果这是真的,你需要匹配不上Option.get( ... ),但paintArr.[i,j].color本身,并处理三种情况:(1)当颜色被Black包裹Some,(2)当颜色被White包裹Some,和(3)当颜色是None:
for i = 0 to 5 do
match paintArr.[i,j].color with
| Some White -> white <- Array.append white paintArr.[i,j]
| Some Black -> black <- Array.append black paintArr.[i,j]
| None -> ()
Run Code Online (Sandbox Code Playgroud)
最后,我可以看到一个循环i,但是在哪里j?我想你只是忘了为它添加一个循环:
for i = 0 to 5 do
for j = 0 to 5 do
match paintArr.[i,j].color with
| Some White -> white <- Array.append white paintArr.[i,j]
| Some Black -> black <- Array.append black paintArr.[i,j]
| None -> ()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
149 次 |
| 最近记录: |