在Rust中,我认为处理可恢复错误的惯用方法是使用Result.例如,这个功能显然是惯用的:
fn do_work() -> Result<u64, WorkError> {...}
Run Code Online (Sandbox Code Playgroud)
当然,还有一些具有单一,明显的故障状态的功能,因此使用Option类型.一个惯用的例子是这样的:
fn do_work() -> Option<u64>
Run Code Online (Sandbox Code Playgroud)
这一切都在文档中直接解决.但是,我对函数可能失败的情况感到困惑,但在成功时没有任何有意义的值.比较以下两个功能:
fn do_work() -> Option<WorkError>
// vs
fn do_work() -> Result<(), WorkError>
Run Code Online (Sandbox Code Playgroud)
我只是不确定哪一个更惯用,或者更常用于现实世界的Rust代码.我这样的问题的首选资源是Rust书,但我不认为这是在" 错误处理 "部分中解决的.我也没有任何其他Rust文档的运气.
当然,这似乎是相当主观的,但我正在寻找权威的来源,要么说明哪种形式是惯用的,要么说明为什么一种形式优于(或劣等)另一种形式.(我也很好奇这个约定如何与其他大量使用"错误作为值"的语言相比,比如Go和Haskell.)
我一般都了解什么类型的擦除以及为什么我们会遇到未经检查的警告.但是,我不明白为什么在以下情况下只发出一个未经检查的警告:
class A[K] {
def receive: PartialFunction[Any, Unit] = {
case ds: List[Double] => // unchecked warning
println("* List[Double]")
case kx: Vector[K] => // no unchecked warning
println("* Vector[K]")
}
}
object TestApp extends App {
val a = new A[Int]
a.receive(List("bar"))
a.receive(Vector("foo"))
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,两个接收呼叫都匹配案例条款.编译器确实对第一个子句发出警告:
警告:类型模式中的非变量类型参数Double [Double]未选中,因为它已被擦除消除.
我知道TypeTag [T]可以用来实现更好的类型安全性.但我关注的是为什么没有为第二个案件条款发出未经检查的警告.据我所知,类型参数K也被删除,并根据Java Generics FAQ
当编译器找到目标类型为参数化类型或类型参数的强制类型转换时,也会报告"未选中"警告
所以我想知道为什么不存在未经检查的警告?
我已经写了近一年的Java了,我已经看到了两种不同的约定,用于人们如何实现他们的setter.
为了说明这一点,以下是两种惯例的示例.(我也很想知道这两个模式的简洁名称)
使用第一个约定的类,不返回其"set"方法.像这样:
public class Classic{
private double _x;
private double _y;
public Classic(){
x = 0;
y = 0;
}
public void setX(double d){//or boolean with a type check on input
x = d;
}
public void sety(double d){
y = d;
}
}
Run Code Online (Sandbox Code Playgroud)
使用替代约定的类从其setter方法返回.像这样:
public class Alternative{
private double _x;
private double _y;
public Alternative(){
x = 0;
y = 0;
}
public Alternative setX(double d){
x = d;
return(this);
}
public Alternative sety(double d){
y = d; …
Run Code Online (Sandbox Code Playgroud) 我想要的是这样的方法:
fn take<T>(vec: Vec<T>, index: usize) -> Option<T>
Run Code Online (Sandbox Code Playgroud)
但是,我找不到这样的方法.我错过了什么吗?或者有一个原因,这实际上是不安全的/无法正确完成.
编辑:这是一个与内置*安全*方式移出Vec <T>的不同问题?
那里的目标是一个Vec
没有超出边界访问的方法(而是返回一个Result).这里我正在寻找一个消耗Vec的方法,并返回其中一个元素.上述问题的答案都没有解决我的问题.
编辑2:为了进一步澄清,我正在寻找一种消耗 Vec并返回一个元素的方法,而没有恢复Vec不变量的方法Vec
和remove
做法.
考虑以下两个特征:
pub trait Foo {
fn new(arg: u32) -> Self;
}
pub trait Bar<P>: Foo {
fn with_parameter(arg: u32, parameter: P) -> Self;
}
Run Code Online (Sandbox Code Playgroud)
我想添加毯子impl:
impl<T: Bar<P>, P: Default> Foo for T {
fn new(arg: u32) -> Self {
Self::with_parameter(arg, P::default())
}
}
Run Code Online (Sandbox Code Playgroud)
但是我得到了编译器错误:
error[E0207]: the type parameter `P` is not constrained by the impl trait, self type, or predicates
--> src/lib.rs:9:17
|
9 | impl<T: Bar<P>, P: Default> Foo for T {
| ^ unconstrained type parameter
Run Code Online (Sandbox Code Playgroud)
我想我得到了这个错误,因为我违反了特质一致性规则,但我不明白究竟会破坏什么规则.为什么不允许这种模式?而且,更重要的是,我可以实现我想要的而不会出错吗?
我有一个Class对象,我想调用一个静态方法.我有以下代码.
Method m=cls.getMethod("main",String[].class);
System.out.println(m.getParameterTypes().length);
System.out.println(Arrays.toString(m.getParameterTypes()));
System.out.println(m.getName());
m.invoke(null,new String[]{});
Run Code Online (Sandbox Code Playgroud)
这打印:
但随后它抛出:
IllegalArgumentException: wrong number of arguments
Run Code Online (Sandbox Code Playgroud)
我在这里俯瞰什么?
我正在尝试编写一个从列表中删除重复项的程序,但我的程序在第 5 行不断抛出错误“列表索引超出范围” if n/(sequence[k]) == 1:
。我无法弄清楚这一点。我认为“k”的可能值为 0、1 和 2 是否正确?将其中任何一个作为可能索引范围之外的索引的“序列”如何?
def remove_duplicates(sequence):
new_list = sequence
for n in sequence:
for k in range(len(sequence)):
if n/(sequence[k]) == 1:
new_list.remove(sequence[k])
print new_list
remove_duplicates([1,2,3])
Run Code Online (Sandbox Code Playgroud) 以下定理在Coq中可证明吗?如果没有,有没有办法证明它不可证明?
Theorem not_for_all_is_exists:
forall (X : Set) (P : X -> Prop), ~(forall x : X, ~ P x) -> (exists x: X, P x).
Run Code Online (Sandbox Code Playgroud)
我知道这种相关关系是真的:
Theorem forall_is_not_exists : (forall (X : Set) (P : X -> Prop), (forall x, ~(P x)) -> ~(exists x, P x)).
Proof.
(* This could probably be shortened, but I'm just starting out. *)
intros X P.
intros forall_x_not_Px.
unfold not.
intros exists_x_Px.
destruct exists_x_Px as [ witness proof_of_Pwitness].
pose (not_Pwitness := forall_x_not_Px witness). …
Run Code Online (Sandbox Code Playgroud) 如何在不使其成为单独变量的情况下传递数组?例如,我知道这有效:
class Test{
public static void main(String[] args){
String[] arbitraryStrings={"foo"};
takesStringArray(arbitraryStrings);
}
public static void takesStringArray(String[] argument){
System.out.println(argument);
}
}
Run Code Online (Sandbox Code Playgroud)
但我不想让数组成为变量,因为它只在这里使用.有没有办法做这样的事情:
class Test{
public static void main(String[] args){
takesStringArray({"foo"});
}
public static void takesStringArray(String[] argument){
System.out.println(argument);
}
}
Run Code Online (Sandbox Code Playgroud) 有没有一种简单的方法来简化比率?例如1875:5625:625
会变成3:9:1
.
我正在使用 Python,但我想知道为什么而不是如何。
java ×3
rust ×3
python ×2
arrays ×1
coding-style ×1
collections ×1
coq ×1
fractions ×1
generics ×1
idiomatic ×1
implication ×1
jvm ×1
list ×1
logic ×1
optional ×1
reflection ×1
rust-result ×1
scala ×1
setter ×1
traits ×1
type-erasure ×1
vector ×1