我正在尝试对类似数据框的结构建模。我知道在这里如何使用use std::any::{Any};
use std::fmt::Debug;
pub trait Value: Any + Sized {
fn as_any(&self) -> &Any {
self
}
fn as_any_mut(&mut self) -> &mut Any {
self
}
}
impl Value for i32 {}
#[derive(Debug)]
struct Frame {
data: Vec<Box<Any>>,
}
fn make_int(of: Vec<i32>) -> Frame {
let data = of.into_iter().map(|x| Box::new(x.as_any())).collect();
Frame {
data: data,
}
}
,但是我正在探索如何与C#/ Python / etc类似。
我尝试关注Rust Trait object conversion,但工作不正常:
error[E0277]: the trait bound `std::vec::Vec<std::boxed::Box<std::any::Any>>: std::iter::FromIterator<std::boxed::Box<&std::any::Any>>` is not satisfied
--> src/main.rs:40:61
|
40 | let data = of.into_iter().map(|x| Box::new(x.as_any())).collect();
| ^^^^^^^ a collection of type `std::vec::Vec<std::boxed::Box<std::any::Any>>` cannot be built from an iterator over elements of type `std::boxed::Box<&std::any::Any>`
|
= help: the trait `std::iter::FromIterator<std::boxed::Box<&std::any::Any>>` is not implemented for `std::vec::Vec<std::boxed::Box<std::any::Any>>`
编译器抱怨:
[root@localhost student_program]# python db_setup.py
Connection successful!!
Database already exists: students
create_table
/usr/local/lib/python3.6/site-packages/pymysql/cursors.py:329: Warning: (1050, " Table 'students_info' already exists")
self._do_get_result()
use students;
Enter the first name :Frank
Enter the last name: Brady
Enter the email address: frank@noemail.com
Enter the address: 300 Main Street, Belfast
Enter the DOB in YYYY-MM-DD: 1980-02-02
Enter the english mark: 90
Enter the maths mark: 80
Enter the history mark: 70
Enter the science mark: 45
('INSERT into students_info (firstname, lastname,email,address,DOB,english,maths,history,science) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s);', ('Frank', 'Brady', 'frank@noemail.com', '300 Main Street, Belfast', '1980-02-02', '90', '80', '70', '45'))
######### Program below #################
import os,pymysql
mariadb_root = '/var/lib/mysql/'
db_to_create = 'students'
conn = pymysql.connect(host='localhost', user='xxx', passwd='xxx', cursorclass=pymysql.cursors.DictCursor)
print('Connection successful!!')
# Check if db exists, if not create
def check_db_exists():
dbfile = os.path.join(mariadb_root, db_to_create)
if not os.path.exists(dbfile):
cur = conn.cursor()
command = "CREATE DATABASE %s;" % db_to_create
print(command)
cur.execute(command)
print("Database created %s:", db_to_create)
else:
print("Database already exists: %s" % db_to_create)
check_db_exists()
def create_database():
cur = conn.cursor()
command = "use %s; " %db_to_create
cur.execute(command)
create_table = ("""
CREATE TABLE IF NOT EXISTS students_info (
ID int NOT NULL AUTO_INCREMENT,
firstname varchar(255),
lastname varchar(255),
email varchar(255),
address varchar(255),
DOB DATE,
english varchar(255),
maths varchar(255),
history varchar(255),
science varchar(255),
PRIMARY KEY (ID));
""")
print("create_table")
cur.execute(create_table)
print(command)
create_database()
def add_student():
firstname = input("Enter the first name :")
lastname = input("Enter the last name: ")
email = input("Enter the email address: ")
address = input("Enter the address: ")
DOB = input("Enter the DOB in YYYY-MM-DD: ")
english = input("Enter the english mark: ")
maths = input("Enter the maths mark: ")
history = input("Enter the history mark: ")
science = input("Enter the science mark: ")
cur = conn.cursor()
command = "use %s; " %db_to_create
cur.execute(command)
cur.execute = ("""INSERT into students_info (firstname, lastname,email,address,DOB,english,maths,history,science) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s);""",
(firstname,lastname,email,address, DOB,english,maths,history,science))
print(cur.execute)
cur.close()
conn.close()
add_student()
答案 0 :(得分:2)
主要问题在于此功能:
fn as_any(&self) -> &Any {
self
}
这意味着您可以借用Value
作为&Any
,(它将&Value
转换为&Any
)。
但是,您想从该Box<Any>
创建一个&Any
。这永远不会起作用,因为&Any
是借来的值,而Box<Any>
是拥有的。
最简单的解决方案是更改特征以返回装箱的值(拥有的特征对象):
pub trait Value: Any + Sized {
fn as_boxed_any(&self) -> Box<Any> {
Box::new(self)
}
//The mut variation is not needed
}
现在make_int
函数很简单:
fn make_int(of: Vec<i32>) -> Frame {
let data = of.into_iter().map(|x| x.as_boxed_any()).collect();
Frame {
data: data,
}
}
更新:稍作修改,我发现您可以通过编写以下内容来创建Vec<Box<Any>>
:
fn make_int(of: Vec<i32>) -> Frame {
let data = of.into_iter().map(|x| Box::new(x) as Box<Any>).collect();
Frame {
data: data,
}
}
如果您仅为此转换编写特征,则实际上并不需要它。