简体   繁体   English

锈“如果让”不起作用?

[英]Rust “if let” not working?

I am wrapping libxml2 in Rust as an exercise in learning the Rust FFI, and I have come across something strange. 我将libxml2封装在Rust中,作为学习Rust FFI的练习,并且遇到了一些奇怪的事情。 I am new to Rust, but I believe the following should work. 我是Rust的新手,但我相信以下应该可行。

In main.rs I have: main.rs我有:

mod xml;

fn main() {
    if let doc = xml::parse_file("filename") {
        doc.simple_function();
    }
}

And xml.rs is: xml.rs是:

extern create libc;

use libc::{c_void, c_char, c_int, c_ushort};
use std::ffi::CString;

// There are other struct definitions I've implemented that xmlDoc
// depends on, but I'm not going to list them because I believe
// they're irrelevant

#[allow(non_snake_case)]
#[allow(non_camel_case_types)]
#[repr(C)]
struct xmlDoc {
    // xmlDoc structure defined by the libxml2 API
}


pub struct Doc {
    ptr: *mut xmlDoc
}

impl Doc {
    pub fn simple_function(&self) {
        if self.ptr.is_null() {
            println!("ptr doesn't point to anything");
        } else {
            println!("ptr is not null");
        }
    }
}

#[allow(non_snake_case)]
#[link(name = "xml2")]
extern {
    fn xmlParseFile(filename: *const c_char) -> *mut xmlDoc;
}

pub fn parse_file(filename: &str) -> Option<Doc> {
    unsafe {
        let result;
        match CString::new(filename) {
            Ok(f) => { result = xmlParseFile(f.as_ptr()); },
            Err(_) => { return None; }
        }
        if result.is_null() {
            return None;
        }
        Some(Doc { ptr: result })
    }
}

I'm wrapping the C struct, xmlDoc in a nice Rust-friendly struct, Doc , to have a clear delineation between the safe (Rust) and unsafe (C) data types and functions. 我将C结构xmlDoc包装在一个很好的Rust友好结构Doc ,以在安全(Rust)和不安全(C)数据类型和函数之间进行清晰的划分。

This all works for the most part except when I compile, I get an error in main.rs: 除了编译时,在main.rs中我都会报错:

src/main.rs:38:13: 38:28 error: no method named 'simple_function' found
for type 'std::option::Option<xml::Doc>' in the current scope
src/main.rs:38         doc.simple_function();
                       ^~~~~~~~~~~~~~~
error: aborting due to previous error`

It seems convinced that doc is an Option<xml::Doc> even though I'm using the if let form that should unwrap the Option type. 似乎确信docOption<xml::Doc>即使我使用的是if let形式,也可以将Option类型解包。 Is there something I'm doing incorrectly? 我做错了什么吗?

match xml::parse_file("filename") {
    Some(doc) => doc.simple_function(),
    None => {}
}

The above works fine, but I'd like to use the if let feature of Rust if I'm able. 上面的方法工作正常,但我想使用Rust的if let功能。

You need to pass the actual pattern to if let (unlike languages like Swift which special case if let for Option types): 您需要将实际的模式传递给if let (与Swift等语言不同, if let Option类型作为if let特殊情况):

if let Some(doc) = xml::parse_file("filename") {
    doc.simple_function();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM