2014-09-13 21 views
5

Hãy xem xét ví dụ saulỗi "loại giá trị này phải được biết trong bối cảnh này" trong mô hình kết hợp

fn main() { 
    f("hello", true); 
} 

fn f(str: &str, sen: bool) { 
    let s: &str = match sen { 
     false => str, 
     true => str.chars().map(|x| x.to_lowercase()).collect().as_slice() 
    }; 
    println!("{}", s); 
} 

Tôi nhận được lỗi này

error: the type of this value must be known in this conntext                                        
true => str.chars().map(|x| x.to_lowercase()).collect().as_slice() 
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

Tôi là một chút bối rối, không phải trình biên dịch biết rằng loại str&str từ định nghĩa hàm? Tôi đang thiếu gì ở đây?

Trả lời

4

Vị trí lỗi có thể gây nhầm lẫn, vấn đề ở đây là phương pháp collect. Nó là chung cho bất kỳ FromIterator và trong trường hợp này trình biên dịch mèo suy ra kiểu (trình biên dịch thấy là bạn cần một số kiểu X thực hiện FromIterator có phương thức as_slice tạo ra một đường dây &).

Vấn đề thứ hai với mã này mà bạn đang cố trả về một tham chiếu đến giá trị cục bộ (kết quả thu thập) từ câu lệnh đối sánh. Bạn không thể làm điều đó bởi vì giá trị đó có tuổi thọ của khối đó và được deallocated sau, do đó, trả về sẽ không hợp lệ.

Một giải pháp làm việc (nhưng nó đòi hỏi chuyển đổi & str để String):

fn main() { 
    f("hello", true); 
} 

fn f(str: &str, sen: bool) { 
    let s: String = match sen { 
     false => str.to_string(), 
     true => str.chars().map(|x| x.to_lowercase()).collect() 
    }; 
    println!("{}", s); 
} 

Tôi không biết những gì bạn đang cố gắng để đạt được cuối cùng nhưng hãy nhìn vào MaybeOwned nếu điều này sẽ là một chức năng trả về một lát (&str) hoặc String.

+0

Cảm ơn. Tôi đã sử dụng các biến tạm thời để lưu trữ 'String' và bind s thành' temp_var.as_slice() '. Không chắc chắn liệu có một cách tốt hơn hay không. –

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