大家好,
我有一个小型色板编辑器,用了一个三种情形的调色板联合类型。全新的编辑是 NotEntered,主动清空是 Empty,Colors 则持有一个列表。我把这几个 case 设成了私有,只暴露 ofColors,其中 ofColors [] 会得到 Empty。我原本以为编译器会让 Colors [] 根本无法构造出来。
在一次脚本化的操作中(新建、添加蓝色、移除蓝色、Save),Save 打印的是 "0 colors",而不是 "empty (chosen)"。Reset 的表现是正确的。Rider 没有显示波浪线,构建也是干净的。
我先怀疑是 List.filter,然后怀疑 Rider 用的 SDK 和 global.json 里指定的不一样,于是我在终端里重新构建了一遍。结果还是一样。
我认为要负责的是下面这个函数。
let remove (name: string) (p: Palette) =
match p with
| Colors cs -> Colors(cs |> List.filter (fun c -> c.Name <> name))
| other -> other
私有性是不是只在 Palette.fs 之外才检查,所以我自己的模块可以随意构造 Colors []?访问控制页面似乎是这个意思,但我不确定。如果是这样,让 add 和 remove 都经过 ofColors 是通常的修法吗,还是说这个类型本身就设计错了?我还在想,用一个普通列表加一个 entered 标志,会不会在这里更简单。
谢谢,
Oskar
从英语翻译·查看原文Hello all,
I have a small swatch editor with a three-case palette union. A fresh edit is NotEntered, a deliberate clear is Empty, and Colors holds a list. I made the cases private and exposed only ofColors, where ofColors [] gives Empty. My expectation was that the compiler would make Colors [] impossible to build.
In a scripted session (fresh, add blue, remove blue, Save), Save prints "0 colors" instead of "empty (chosen)". Reset behaves correctly. Rider shows no squiggle and the build is clean.
I suspected List.filter first, then Rider using a different SDK than global.json, so I rebuilt from the terminal. The result was the same.
This is the function I think is responsible:
let remove (name: string) (p: Palette) =
match p with
| Colors cs -> Colors(cs |> List.filter (fun c -> c.Name <> name))
| other -> other
Is the privacy only checked outside Palette.fs, so my own module can build Colors [] freely? The access control page seems to suggest so, but I am not certain. If so, is routing add and remove through ofColors the normal fix, or is the type itself wrong? I am also wondering whether a plain list plus an entered flag would be simpler here.
Thank you,
Oskar