You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust编写Python扩展:二维bool数组行XOR编译错误解决

问题:Rust编写Python扩展时数组异或操作报错

我要写一个能被Python调用的Rust函数,需求很简单:接收二维布尔数组,把第二行和第一行做XOR操作后赋值给第一行。代码如下:

use numpy::PyArray2;
use pyo3::prelude::{pymodule, PyModule, PyResult, Python};

#[pymodule]
fn state_generator(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
    #[pyfn(m)]
    fn random_cnots_transformation(_py: Python<'_>, x: &PyArray2<bool>) {
        let mut array = unsafe { x.as_array_mut() };
        let source = array.row(1);
        let mut target = array.row_mut(0);

        target ^= source;
    }

    Ok(())
}

用maturin编译时出现以下错误:

error[E0271]: type mismatch resolving `<ViewRepr<&mut bool> as RawData>::Elem == ArrayBase<ViewRepr<&bool>, Dim<[usize; 1]>>`
  --> src/lib.rs:35:16
   |
35 |         target ^= source;
   |                ^^ expected `bool`, found `ArrayBase<ViewRepr<&bool>, Dim<[usize; 1]>>`
   |
   = note: expected type `bool`
            found struct `ArrayBase<ViewRepr<&bool>, Dim<[usize; 1]>>`
   = note: required for `ArrayBase<ViewRepr<&mut bool>, Dim<[usize; 1]>>` to implement `BitXorAssign<ArrayBase<ViewRepr<&bool>, Dim<[usize; 1]>>>`

error[E0277]: the trait bound `ArrayBase<ViewRepr<&bool>, Dim<[usize; 1]>>: ScalarOperand` is not satisfied
  --> src/lib.rs:35:16
   |
35 |         target ^= source;
   |                ^^ the trait `ScalarOperand` is not implemented for `ArrayBase<ViewRepr<&bool>, Dim<[usize; 1]>>`
   |
   = help: the following other types implement trait `ScalarOperand`:
             bool
             isize
             i8
             i16
             i32
             i64
             i128
             usize
           and 9 others
   = note: required for `ArrayBase<ViewRepr<&mut bool>, Dim<[usize; 1]>>` to implement `BitXorAssign<ArrayBase<ViewRepr<&bool>, Dim<[usize; 1]>>>`

error[E0271]: type mismatch resolving `<ViewRepr<&bool> as RawData>::Elem == ArrayBase<ViewRepr<&bool>, Dim<[usize; 1]>>`
  --> src/lib.rs:35:16
   |
35 |         target ^= source;
   |                ^^ expected `bool`, found `ArrayBase<ViewRepr<&bool>, Dim<[usize; 1]>>`
   |
   = note: expected type `bool`
            found struct `ArrayBase<ViewRepr<&bool>, Dim<[usize; 1]>>`
   = note: required for `ArrayBase<ViewRepr<&bool>, Dim<[usize; 1]>>` to implement `BitXorAssign`
   = note: 1 redundant requirement hidden
   = note: required for `ArrayBase<ViewRepr<&mut bool>, Dim<[usize; 1]>>` to implement `BitXorAssign<ArrayBase<ViewRepr<&bool>, Dim<[usize; 1]>>>`

error[E0277]: the trait bound `ViewRepr<&bool>: DataMut` is not satisfied
  --> src/lib.rs:35:16
   |
35 |         target ^= source;
   |                ^^ the trait `DataMut` is not implemented for `ViewRepr<&bool>`
   |
   = help: the trait `DataMut` is implemented for `ViewRepr<&'a mut A>`
   = note: required for `ArrayBase<ViewRepr<&bool>, Dim<[usize; 1]>>` to implement `BitXorAssign`
   = note: 1 redundant requirement hidden
   = note: required for `ArrayBase<ViewRepr<&mut bool>, Dim<[usize; 1]>>` to implement `BitXorAssign<ArrayBase<ViewRepr<&bool>, Dim<[usize; 1]>>>`

我以为是^=操作符的问题,换成+=还是报错:

error[E0368]: binary assignment operation `+=` cannot be applied to type `ArrayBase<ViewRepr<&mut bool>, Dim<[usize; 1]>>`
  --> src/lib.rs:35:9
   |
35 |         target += source;
   |         ------^^^^^^^^^^
   |         |
   |         cannot use `+=` on type `ArrayBase<ViewRepr<&mut bool>, Dim<[usize; 1]>>`

我看过相关的技术回答,但不确定差异在哪里。我猜问题出在我的array是ArrayViewMut<bool, Ix2>,而示例里是Array2。请问要修改哪些部分才能实现这个操作?

我的Cargo版本是1.72.0,Cargo.toml配置如下:

[package]
name = "state_generator"
version = "0.1.0"
authors = ["Tristan NEMOZ"]
edition = "2021"

[lib]
crate-type = ["cdylib"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
ndarray = "0.15.6"
numpy = "0.19.0"
rand = "0.8.5"

[dependencies.pyo3]
version = "0.19.2"
features = ["extension-module"]

解决方案

问题核心是:ndarray的视图(ArrayView/ArrayViewMut)没有直接实现数组间的BitXorAssign批量操作,需要改用元素级遍历的方式完成异或。

修改后的代码如下:

use numpy::PyArray2;
use ndarray::Zip;
use pyo3::prelude::{pymodule, PyModule, PyResult, Python};

#[pymodule]
fn state_generator(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
    #[pyfn(m)]
    fn random_cnots_transformation(_py: Python<'_>, x: &PyArray2<bool>) {
        let mut array = unsafe { x.as_array_mut() };
        let source = array.row(1);
        let mut target = array.row_mut(0);

        // 使用Zip工具逐元素执行异或
        Zip::from(&mut target)
            .and(&source)
            .for_each(|t, s| *t ^= *s);
    }

    Ok(())
}

说明

  1. Zip是ndarray提供的高效元素遍历工具,能安全同步遍历多个数组/视图的对应元素
  2. 直接操作每个元素的引用,避开了视图间批量操作符未实现的问题
  3. 保持原逻辑,直接修改输入数组,无需额外内存分配

也可以用基础的迭代器组合实现,效果一致:

for (t, s) in target.iter_mut().zip(source.iter()) {
    *t ^= *s;
}

这两种方式都能解决类型不匹配问题,同时保证执行效率。


内容的提问来源于stack exchange,提问作者Tristan Nemoz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 14:39:49