已关闭,此问题需要更focused,目前不接受回答。
**要改进此问题吗?**更新问题,使其仅关注editing this post的一个问题。
2天前关闭。
Improve this question
请查看以下两个函数和错误信息。
是否可以在不使用clone()
或copy()
函数的情况下修复这两个函数?
另外,你能回答评论中的问题吗?
pub fn Vec3::transform(vector: Vec3, matrix: Matrix3x3) -> Vec3
{
return Vec3
{
integer: vector.integer * matrix.integer,
double: vector.double * matrix.double,
string: vector.string + &matrix.string,//why is "&" needed here as we are not modifying matrix.string?
}
}
pub fn Rototranslation::apply_mut(&self, vector: &Vec3) -> Vec3 //why is not a "mut" needed here?
{
let transformed_vector = *vector - self.origin_vector;//why do we need a dereference here?
let temp_matrix = &self.rotation_matrix;
let transformed_vector = Vec3::transform(transformed_vector, temp_matrix);
return transformed_vector + self.origin_vector;
}
输出
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/main.rs:141:70
|
141 | let transformed_vector = Vec3::transform(transformed_vector, &mut temp_matrix);
| --------------- ^^^^^^^^^^^^^^^^ expected struct `Matrix3x3`, found `&mut &Matrix3x3`
| |
| arguments to this function are incorrect
|
note: associated function defined here
--> src/main.rs:49:12
|
49 | pub fn transform(vector: Vec3, matrix: Matrix3x3) -> Vec3 // a fake operation
| ^^^^^^^^^ -----------------
For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to previous error
完整源代码
use std::ops::{Add, Sub};
struct Vec3
{
pub integer: i32,
pub double: f64,
pub string: String,
}
impl Add<Vec3> for Vec3 //overloaded binary addition operator for Vec3
{
type Output = Vec3;
fn add(self, other: Vec3) -> Vec3
{
Vec3
{
integer: self.integer + other.integer,
double: self.double + other.double,
string: self.string + &other.string,
}
}
}
impl Sub<Vec3> for Vec3 //overloaded binary subtraction operator for Vec3
{
type Output = Vec3;
fn sub(self, other: Vec3) -> Vec3
{
Vec3
{
integer: self.integer - other.integer,
double: self.double - other.double,
string: self.string.replace(&other.string, ""),
}
}
}
impl Vec3
{
pub fn new(integer: i32, double: f64, string: String) -> Vec3
{
return Vec3 //constructing and returning a Vec3 object
{
integer,
double,
string,
}
}
pub fn transform(vector: Vec3, matrix: Matrix3x3) -> Vec3 // a fake operation
{
return Vec3
{
integer: vector.integer * matrix.integer,
double: vector.double * matrix.double,
string: vector.string + &matrix.string,
}
}
pub fn print(&self)
{
print!("{} ", self.integer);
print!("{} ", self.double);
print!("{} \n", self.string);
}
}
struct Matrix3x3 // A fake Matrix type
{
pub integer: i32,
pub double: f64,
pub string: String,
}
impl Add<Matrix3x3> for Matrix3x3 //overloaded binary addition operator for Matrix3x3
{
type Output = Matrix3x3;
fn add(self, other: Matrix3x3) -> Matrix3x3
{
Matrix3x3
{
integer: self.integer + other.integer,
double: self.double + other.double,
string: self.string + &other.string,
}
}
}
impl Sub<Matrix3x3> for Matrix3x3 //overloaded binary subtraction operator for Matrix3x3
{
type Output = Matrix3x3;
fn sub(self, other: Matrix3x3) -> Matrix3x3
{
return Matrix3x3
{
integer: self.integer - other.integer,
double: self.double - other.double,
string: self.string.replace(&other.string, ""),
}
}
}
impl Matrix3x3
{
pub fn new(integer: i32, double: f64, string: String) -> Matrix3x3
{
return Matrix3x3 //constructs a Matrix3x3 object and returns it
{
integer,
double,
string,
}
}
pub fn print(&self)
{
print!("{} ", self.integer);
print!("{} ", self.double);
print!("{} \n", self.string);
}
}
struct Rototranslation
{
pub origin_vector: Vec3,
pub rotation_matrix: Matrix3x3,
}
impl Rototranslation
{
pub fn new(my_vec: Vec3, mat: Matrix3x3) -> Rototranslation
{
return Rototranslation
{
origin_vector: my_vec,
rotation_matrix: mat,
}
}
// A fake operation
pub fn apply_mut(&self, vector: &Vec3) -> Vec3
{
let transformed_vector = *vector - self.origin_vector;
let temp_matrix = &self.rotation_matrix; // "&" needed here coz we are not using copy or clone
let transformed_vector = Vec3::transform(transformed_vector, temp_matrix);
return transformed_vector + self.origin_vector;
}
fn print(&self)
{
self.origin_vector.print();
self.rotation_matrix.print();
}
}
fn main()
{
let _vec: Vec3 = Vec3::new(10, 0.01, "hello".to_string());
_vec.print();
let _mat: Matrix3x3 = Matrix3x3::new(10, 0.01, "hello".to_string());
_mat.print();
let _rot: Rototranslation = Rototranslation::new(_vec, _mat);
_rot.print();
let mut _vec2: Vec3 = Vec3::new(10, 0.01, "hello".to_string());
_vec2.print();
let _rotated_vec = _rot.apply_mut(&_vec2);// "&" used because we are expecting _vec2's value change
}
1条答案
按热度按时间fzsnzjdm1#
是否可以在不使用
clone()
或copy()
函数的情况下修复这两个函数?Yes。问题并不是真正的转换(尽管我确信在其他上下文中它会引起问题,特别是我不知道为什么它会按值获取转换矩阵)。
它是你实现
Add
和Sub
作为移动操作,对两个参数(又名Trait<T> for T
),所以初始减法和最终加法都试图消耗origin_vector
,他们不能这样做,因为它只能通过借用访问。解决办法是:
impl Sub<&Vec3> for &Vec3
而不是当前的,这样减法只会借用,replace
无论如何都会创建一个新的字符串,所以不需要转移所有权。impl Add<&Vec3> for Vec3
,这样就可以用借用的Vec3添加自己的Vec3,这是尾部添加所需的。然后,您还需要分别修复相应表达式的借用。
和
因为标准库实现了
Add<&str> for String
。matrix.string
是一个String
,所以您需要将其转换为&str
(或者足够接近,&String
是由于deref强制。另外,
&
特别不允许突变,你可能想读一下Rust的书或其他东西?&
是一个不可变的引用类型。因为不管你的命名方案如何,你都没有发生任何变异?
Vec3 - Vec3
创建了一个新的Vec3
,Vec3::transform
也是如此,还有Vec3 + Vec3
。没有看到任何变异。因为你的
impl Add<Vec3> for Vec3
,所以你的加法想要通过值接收两个Vec3,但是vector
是一个&Vec3
。所以类型不匹配。当然,你会得到一个借用检查错误,因为你不能从一个共享引用中 * 移动 * 一个值(这是你的Add的impl要求的),而且
Vec3
不是Copy
。