type bytesLookup = Map<byte,int list>
type lookupList = bytesLookup list
let maps:bytesLookup = Map.empty
let printArg arg = printfn(Printf.TextWriterFormat<unit>(arg))
let array1 = [|byte(0x02);byte(0xB1);byte(0xA3);byte(0x02);byte(0x18);byte(0x2F)|]
let InitializeNew(maps:bytesLookup,element,index) =
maps.Add(element,List.empty<int>)(*KeyNotFoundException*)
maps.[element]
let MapArray (arr:byte[],maps:bytesLookup ) =
for i in 0..arr.Length do
match maps.TryFind(arr.[i]) with
| Some(e) -> i::e
| None -> InitializeNew(maps,arr.[i],i)
MapArray(array1,maps);
printArg( maps.Count.ToString())
异常
System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary. at Microsoft.FSharp.Collections.MapTreeModule.find[TValue,a](IComparer
1 comparer, TValue k, MapTree
2 m) at Microsoft.FSharp.Collections.FSharpMap2.get_Item(TKey key) at FSI_0012.MapArray(Byte[] arr, FSharpMap
2 maps) in Script1.fsx:line 16 at .$FSI_0012.main@() in Script1.fsx:line 20
在函数中,我试图用一个 int 列表初始化 map 中的一个新元素。我还尝试同时将一个新的 int 值推送到列表中。
我做错了什么?
最佳答案
F# Map
是一个不可变的数据结构,Add
方法不修改现有的数据结构,它返回一个新的 Map
加上你所要求的。
观察:
let ex1 =
let maps = Map.empty<byte, int list>
maps.Add(1uy, [1]) // compiler warning here!
maps.[1uy]
这段代码有两点:
它抛出
System.Collections.Generic.KeyNotFoundException
当你运行它时它给你一个编译器警告,即
maps.Add...
行应该有类型unit
但实际上有类型Map<byte,int list>
.不要忽视警告!
现在试试这个:
let ex2 =
let maps = Map.empty<byte, int list>
let maps2 = maps.Add(1uy, [1])
maps2.[1uy]
没有警告。没有异常(exception)。代码按预期工作,返回值 [1]
.
关于F# 在 KeyNotFoundException 中添加值以映射结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45220333/