向量上的 Rust 模式匹配
教程展示了一些非常基本的模式匹配示例,例如整数匹配模拟 C 风格的 switch 语句。本教程还展示了如何对元组类型进行基本解构,以及解构结构。
似乎应该可以对向量进行模式匹配,但我无法找出它的正确语法,而且我还没有找到任何示例。
例如,在 Haskell 中,你可以轻松地解构一个列表:
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr func initValue [] = initValue
foldr func initValue (x:xs) = func initValue $ foldr initValue func xs
所以,看一下粗略的翻译,如果能够做到这一点那就太好了:
fn foldr<A, B>(func: fn(A, B) -> B,
initValue: B,
vals: [A]) -> B {
alt vals {
[] { ret initValue; }
_ {
let h = vec::head(vals),
t = vec::tail(vals);
ret foldr(func, func(initValue, h), t);
}
}
}
注意:我知道你可以在这里使用 if 语句,我只是使用这个作为向量上模式匹配的示例。
当前返回:
patterns.rs:10:4: 10:5 error: constant contains unimplemented expression type
patterns.rs:10 [] { ret initValue; }
^
error: aborting due to previous errors
教程中有一个解构结构(用 { .. }
定义)和元组(用 ( .. )
),所以看起来应该有对向量的内置支持,考虑到它们还包含特殊的语法(用 [ .. ]
定义)。
如果我也以错误的方式使用向量,请随时纠正我。
The tutorial shows some very basic examples of pattern matching, such as matching over an integer to emulate a c-style switch statement. The tutorial also shows how to do basic destructuring over a tuple type, and destructuring structures.
It seems like it should be possible to pattern match over a vector but I cannot figure out the right syntax for it and I haven't found any examples of it.
For example, in Haskell you can easily destructure a list:
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr func initValue [] = initValue
foldr func initValue (x:xs) = func initValue $ foldr initValue func xs
So, looking at a rough translation, it would be nice to be able to do:
fn foldr<A, B>(func: fn(A, B) -> B,
initValue: B,
vals: [A]) -> B {
alt vals {
[] { ret initValue; }
_ {
let h = vec::head(vals),
t = vec::tail(vals);
ret foldr(func, func(initValue, h), t);
}
}
}
Note: I know you could use an if statement here, I am just using this as an example of pattern matching over a vector.
This currently returns:
patterns.rs:10:4: 10:5 error: constant contains unimplemented expression type
patterns.rs:10 [] { ret initValue; }
^
error: aborting due to previous errors
There is an example in the tutorial for destructuring structures (defined with { .. }
) and tuples (defined with ( .. )
), so it seems like there should be built-in support for vectors as well considering they also contain a special syntax (defined with [ .. ]
).
Feel free to correct me if I am using vectors in the wrong way as well.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您需要切片模式:
You need slice patterns:
我希望我可以就如何最好地在向量上使用模式匹配提供更一般的建议,但以下是如何使用它们来测试空向量(至少我认为这就是 Haskell 代码正在做的事情。 ..):
请注意,尝试简单地将
[]
作为参数传递会失败,因为编译器无法推断向量的类型。似乎可以在不首先声明的情况下传递[()]
(内部带有nil
的向量),但alt
语句似乎无法测试头表达式是否匹配[()]
(它只是落入默认值)。总而言之,向量目前看起来有点粗糙。如果您认为 Rust 似乎不支持某些特定用途,开发人员非常愿意接受建议和批评:https://mail.mozilla.org/listinfo/rust-dev
另请参阅参考手册以获取更正式的定义,以及一些有助于澄清问题的示例:http://doc.rust-lang.org/doc/rust.html#alternative -表达式
I wish I could give more general advice on how to best use pattern matching on vectors, but here's how you can use them to test for empty vectors (at least I think that's what that Haskell code is doing...):
Note that trying to simply pass
[]
as an argument fails because the compiler can't infer a type for the vector. It seems to be possible to pass[()]
(a vector with anil
inside) without first declaring it, but thealt
statement seems incapable of testing to see if the head expression matches[()]
(it simply falls through to the default).All in all, vectors seem a little rough at the moment. If there's some specific use you have in mind that Rust doesn't seem to support, the developers are quite open to suggestions and critcism: https://mail.mozilla.org/listinfo/rust-dev
Also see the reference manual for a more formal definition, and a few more examples to help clarify things: http://doc.rust-lang.org/doc/rust.html#alternative-expressions
完整地
匹配
向量并保护匹配臂:向量长度超过 10 时,切片模式解决方案变得有点庞大,对于动态长度,它根本不起作用,例如对于像这样的查询
如果v.len() > > 7.
。游乐场
match
the vector in complete and guard the match arms:The slice pattern solution becomes a bit bulky from vector lengths above 10 and for dynamic lengths it doesn't work at all, e.g. for a query like
if v.len() > 7
.Playground