< 返回版块

ugdbg 发表于 2020-07-27 18:11

Tags:macro,never read,warn

代码

use std::any::Any;

macro_rules! using_a {
    ($($x:expr),*) => {
        {
            let mut next = true;
            let mut string = String::new();
            $(
                if let Some(x) = (&$x as &dyn Any).downcast_ref::<&str>() {
                    if next {
                        if (string.len() != 0) {
                            string.push_str(" ");
                        }
                        string.push_str(x);
                    }
                    next = true;
                } else if let Some(x) = (&$x as &dyn Any).downcast_ref::<bool>() {
                    next = *x;
                }
            )*
            string
        }
    }
}

fn main() {
    println!("{}", using_a!{
        "1",
        false,
        "2",
        "3",
        true,
        "4",
        "5",
        false,
        "6",
        "7"
    });
}

期望结果

1 3 4 5 7

报警告

value assigned to `next` is never read
`#[warn(unused_assignments)]` on by default
maybe it is overwritten before being read?rustc(unused_assignments)
main.rs(16, 21): Error originated from macro here
value assigned to `next` is never read
maybe it is overwritten before being read?rustc(unused_assignments)
main.rs(18, 21): Error originated from macro here

代码执行结果没问题,但是为啥会报这个警告?很疑惑 还有使用downcast_ref获取类型,这样使用正确吗? 新手求解惑

playground https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=487138c4647ed9c1c031e321dde58172

评论区

写评论
作者 ugdbg 2020-07-31 00:11

谢谢,学到很多东西

--
👇
gwy15: 能编译期做为什么要用 any

macro_rules! _filter {
    (true, $x:literal) => { concat!($x) };
    (true, $x:literal, $($rest:tt),*) => {
        concat!($x, " ", _filter!($($rest),*))
    };

    (false, $_:literal) => { "" };
    (false, $_:literal, $($rest:tt),*) => {
        _filter!($($rest),*)
    };

    ($x:literal) => { concat!($x) };
    ($x:literal, $($args:tt),*) => {
        concat!($x, " ", _filter!($($args),*))
    };
}

macro_rules! filter_next {
    ($($args:tt),*) => {
        _filter!($($args),*).trim()
    };
}

#[test]
fn test_macro() {
    macro_rules! test {
        ({$($args:tt),*}, $ans:expr) => {
            assert_eq!(
                filter_next!($($args),*),
                $ans
            );
        }
    };
    test!({ 1 }, "1");
    test!({ "1" }, "1");
    test!({1,2}, "1 2");
    test!({1,2,3}, "1 2 3");
    test!({1,2,3,4,5,6,7}, "1 2 3 4 5 6 7");
    test!({"1", "2", 3, "4", 5, 6, "7"}, "1 2 3 4 5 6 7");

    test!({false, 1}, "");
    test!({false, 1,2,3,4}, "2 3 4");

    test!({true, 1}, "1");
    test!({true, "1"}, "1");
    test!({true, 1, 2, 3, 4}, "1 2 3 4");

    test!({true, "1", false, "4", "2", 3, 4, false, 5}, "1 2 3 4");
    test!({true, "1", false, "4", 2, false, 2, false, 2, "3", 4, false, 5}, "1 2 3 4");
    test!({"1", false, "2", "3", true, "4", "5", false, "6", "7"}, "1 3 4 5 7");
}

作者 ugdbg 2020-07-31 00:08

原来如此,明白了,谢谢

--
👇
whfuyn: 宏展开后,最后一次对next的赋值不会被读到。

fn main() {
    let mut next = true;
    if next {
        next = true;
    }
    if next {
        next = true; // warning: value assigned to `next` is never read
    }
}
whfuyn 2020-07-29 21:35

宏展开后,最后一次对next的赋值不会被读到。

fn main() {
    let mut next = true;
    if next {
        next = true;
    }
    if next {
        next = true; // warning: value assigned to `next` is never read
    }
}
gwy15 2020-07-28 10:34

能编译期做为什么要用 any

macro_rules! _filter {
    (true, $x:literal) => { concat!($x) };
    (true, $x:literal, $($rest:tt),*) => {
        concat!($x, " ", _filter!($($rest),*))
    };

    (false, $_:literal) => { "" };
    (false, $_:literal, $($rest:tt),*) => {
        _filter!($($rest),*)
    };

    ($x:literal) => { concat!($x) };
    ($x:literal, $($args:tt),*) => {
        concat!($x, " ", _filter!($($args),*))
    };
}

macro_rules! filter_next {
    ($($args:tt),*) => {
        _filter!($($args),*).trim()
    };
}

#[test]
fn test_macro() {
    macro_rules! test {
        ({$($args:tt),*}, $ans:expr) => {
            assert_eq!(
                filter_next!($($args),*),
                $ans
            );
        }
    };
    test!({ 1 }, "1");
    test!({ "1" }, "1");
    test!({1,2}, "1 2");
    test!({1,2,3}, "1 2 3");
    test!({1,2,3,4,5,6,7}, "1 2 3 4 5 6 7");
    test!({"1", "2", 3, "4", 5, 6, "7"}, "1 2 3 4 5 6 7");

    test!({false, 1}, "");
    test!({false, 1,2,3,4}, "2 3 4");

    test!({true, 1}, "1");
    test!({true, "1"}, "1");
    test!({true, 1, 2, 3, 4}, "1 2 3 4");

    test!({true, "1", false, "4", "2", 3, 4, false, 5}, "1 2 3 4");
    test!({true, "1", false, "4", 2, false, 2, false, 2, "3", 4, false, 5}, "1 2 3 4");
    test!({"1", false, "2", "3", true, "4", "5", false, "6", "7"}, "1 3 4 5 7");
}

作者 ugdbg 2020-07-27 22:45

可能是我逻辑有问题, 进入if时next始终为true, 进入else if时next可能是true或false, 看着是没问题的, 谢谢,我再琢磨琢磨

--
👇
Neutron3529: 大概是宏展开的时候,发现你在玩花:

let mut next=true;
if(next){...next=true}// * //
next=false//读到a后面那个false
if(next){...next=true}

编译器应该是认为标记// * //的if里面那句对next的赋值多余

这个warning应该跟下面这个栗子类似

fn main() {
    let mut next=true;
    if next{next=false}
    next=true;
    println!("{:?}",next)
}

会报同样的warning:

   Compiling playground v0.0.1 (/playground)
warning: value assigned to `next` is never read
 --> src/main.rs:3:13
  |
3 |     if next{next=false}
  |             ^^^^
  |
  = note: `#[warn(unused_assignments)]` on by default
  = help: maybe it is overwritten before being read?

warning: 1 warning emitted

至于downcast对不对……对不起我还没学到那么高深的指令

Neutron3529 2020-07-27 19:23

大概是宏展开的时候,发现你在玩花:

let mut next=true;
if(next){...next=true}// * //
next=false//读到a后面那个false
if(next){...next=true}

编译器应该是认为标记// * //的if里面那句对next的赋值多余

这个warning应该跟下面这个栗子类似

fn main() {
    let mut next=true;
    if next{next=false}
    next=true;
    println!("{:?}",next)
}

会报同样的warning:

   Compiling playground v0.0.1 (/playground)
warning: value assigned to `next` is never read
 --> src/main.rs:3:13
  |
3 |     if next{next=false}
  |             ^^^^
  |
  = note: `#[warn(unused_assignments)]` on by default
  = help: maybe it is overwritten before being read?

warning: 1 warning emitted

至于downcast对不对……对不起我还没学到那么高深的指令

1 共 6 条评论, 1 页