2017-02-20 19 views
9

tôi muốn kiểm tra xem một chuỗi chứa '$' và nếu có cái gì đó sau khi '$':Có thể kết hợp hai mẫu, một mẫu với bộ bảo vệ khớp, trong cùng một nhánh khớp không?

Tôi đã thử mã này:

fn test(s: String) { 
    match s.find('$') { 
     None | (Some(pos) if pos == s.len() - 1) => { 
      expr1(); 
     } 
     _ => { expr2(); } 
    } 
} 

Nhưng nó không biên dịch:

error: expected one of `)` or `,`, found `if` 

là nó không thể kết hợp NoneSome trong một trận đấu-cánh tay?

Nếu có, có cách nào đơn giản để không sao chép expr1() ngoại trừ di chuyển nó vào một chức năng riêng biệt?

Trả lời

7

Đó là không thể có trận phục kích bất ngờ (các if thingy) chỉ áp dụng cho một mẫu thay thế (những điều ngăn cách bởi | ký tự). Chỉ có một bảo vệ phù hợp cho mỗi cánh tay và nó áp dụng cho tất cả các mẫu của cánh tay đó.

Tuy nhiên, có nhiều giải pháp cho vấn đề cụ thể của bạn. Ví dụ:

if s.find('$').map(|i| i != s.len() - 1).unwrap_or(false) { 
    expr2(); 
} else { 
    expr1(); 
} 
+3

Công trình này, nhưng dựa trên thực tế là '$' là ASCII và do đó chiếm một byte. Một giải pháp tổng quát hơn có thể sử dụng ['char :: len_utf8'] (https://doc.rust-lang.org/std/primitive.char.html#method.len_utf8):' i! = S.len() - 'c'.len_utf8() '. – Shepmaster

+2

Tôi muốn ở trên các mã golf: 's.chars(). Skip_while (| i | i! = '$'). Skip (1) .next(). Is_some()' là rõ ràng hơn nhiều so với bất kỳ tính toán chỉ mục imo –

Các vấn đề liên quan