如何匹配作为 Struct 属性的 Box<T> 中的 <T> 值?

How to match value of <T> in Box<T> that is attribute of a Struct?

我正在尝试使用 sqlparser crate and I got stuck on BinaryOp struct that is value of Expr enum and the struct itself contains Expr enum 解析一个简单的查询。

我可以通过匹配打印输出:

sqlparser::ast::Expr::BinaryOp{left:a , op: b , right: c} => println!("{:?}",a)

但是当我尝试从中获取 Expr 时,出现以下错误:

error[E0308]: mismatched types
  --> src/main.rs:41:57
   |
38 | ...                   BinaryOp{left:a , op: b , right: c} => match *a {
   |                                                                    --
   |                                                                    |
   |                                                                    this expression has type `Box<Expr>`
   |                                                                    help: consider dereferencing the boxed value: `**a`
...
41 | ...                       sqlparser::ast::Expr::CompoundIdentifier(w) => {},
   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Box`, found enum `Expr`
   |
   = note: expected struct `Box<Expr>`
                found enum `Expr`

我认为这是解引用的问题,但是即使我添加了解引用(*a)也无法解决它。

完整代码在这里:

use sqlparser::dialect::GenericDialect;
use sqlparser::parser::Parser;
use sqlparser::ast::Statement::Query;
use sqlparser::ast::SetExpr;
use sqlparser::ast::Expr::BinaryOp;



fn main() {
    let dialect = GenericDialect {}; // or AnsiDialect

    let sql = "SELECT a,b FROM table_1 T1 left join table_2 T2 on T1.z = T2.z";

    let ast = &Parser::parse_sql(&dialect, sql).unwrap()[0];

    if let Query(x) = ast {
        match &x.body {
            SetExpr::Select(s) => {let projection = &s.projection;
                                   let from = &s.from;
                                   //let group = &s.group_by;

                                   for p in projection {
                                       if let sqlparser::ast::SelectItem::UnnamedExpr(i) = p {
                                           match i {
                                                sqlparser::ast::Expr::Identifier(r) => println!("{:?}", r.value),
                                                _ => {},
                                           };
                                       }
                                   }

                                   for f in from {
                                       //println!("{:?}",f.relation);
                                       for j in &f.joins {
                                           match &j.join_operator {
                                            sqlparser::ast::JoinOperator::Inner(inj) => println!("inner join {:?}",inj),
                                            sqlparser::ast::JoinOperator::LeftOuter(lfj) => match lfj {
                                                sqlparser::ast::JoinConstraint::On(on) => match on {
                                                    BinaryOp{left:a , op: b , right: c} => match *a {
                                                    
                                                        
                                                        sqlparser::ast::Expr::CompoundIdentifier(w) => {},

                                                        _ => {}
                                                    },
                                                _ => {}
                                                },
                                                _ => {}
                                            },
                                            _ => {}
                                            }
                                        }
                                    }
            },                      
            _ => {}
        }
    }
}

  

如何从 BinaryOp 结构中获取装箱值?

谢谢。

变量 a 的类型为 &Box<Expr>,因此当您取消引用它 *a 时,它只会删除引用,只留下 Box<Expr>。不幸的是,您不能对 Box 中的值进行模式匹配(参见 ),因此您必须再次 取消引用它以获得 Expr

match **a {

然而,匹配臂将尝试变量w移出**a,这是不允许的,因为它在一个共享的后面参考。

您可以通过 &**a 引用 Expr 或绑定到 ref w 而不仅仅是 w 来避免完全移动。如果这对你来说看起来像太多的符号汤,另一种选择是使用 a.as_ref() (通过 AsRef 特征)。