F#可以轻松解压元组。解包列表也是可行的,但编译器会发出警告:
let m = [1; 2; 3]
let [a; b; c] = m
// Incomplete pattern matches on this expression. For example, the value '[_;_;_;_]' may indicate a case not covered by the pattern(s)
有没有办法避免这种警告?
答案 0 :(得分:5)
您可以使用#nowarn
指令(在您的情况下为#nowarn "25"
)禁用每个文件的警告,也可以使用--nowarn
在命令行上禁用警告。
查看F# Compiler Directives了解详情。
首次禁用时,目前无法再次重新启用警告。
如果无法将元素数量解压缩到[a;b;c]
,您的匹配可能会(意外地)导致运行时错误,因此您可以使用明确关于risc的完整匹配:
let m = [1;2;3]
let (a,b,c) =
match m with
| [a;b;c] -> (a,b,c)
| _ -> failwith "Expected exactly three items in m"
答案 1 :(得分:4)
如果您的列表m
包含2个或4个元素,会发生什么?
显然有一种方式,简单的旧模式匹配:
let a, b, c =
match m with
| [a;b;c] -> a,b,c
| _ -> ... // handle the length!=3 case
F#允许您在明确表示您只需要覆盖一个案例时解构右侧对象。这是元组的情况,因为只有一个元组类型可以匹配左侧和右侧。这样的东西显然不会编译,因为类型不匹配:
let m = 1, 2
let a, b, c = m
然而,在您的情况下,并不能保证您在这种情况下实际上并不是这样:
let m = [ 1; 2 ]
let [1;2;3] = m
实际上,您要求编译器允许非详尽的模式匹配。您可以按照其他答案中的说明禁用警告,但是您可以通过这种方式调用运行时错误。
答案 2 :(得分:1)
一个显而易见但却不优雅的方式是:
let m = [1; 2; 3]
let a = List.item 0 m
let b = List.item 1 m
let c = List.item 2 m
您可以编写辅助函数以使其更整洁:
let unpack3 x = (List.item 0 x, List.item 1 x, List.item 2 x)
let (a, b, c) = unpack3 m
如果你知道你总是会有固定数量的物品,那么list
基本上不合适。