Rust传递tiberius Client到函数时的泛型参数错误解决
正确的函数参数写法
方法1:泛型约束自动推导
将drop_table定义为泛型函数,让编译器自动适配Client的底层流类型,这是最灵活的写法:
use tokio::io::{AsyncRead, AsyncWrite}; async fn drop_table<S>(&self, client: &mut Client<S>) -> Result<(), AuthoritiesError> where S: AsyncRead + AsyncWrite + Unpin + Send, { let table_name = format!("Authorities{}", self.year); let schema_table_name = format!("TaxStatements.{}", table_name); log::info!("table_name {:?}", table_name); log::info!("schema_table_name {:?}", schema_table_name); let query = format!(r#" IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'TaxStatements' AND TABLE_NAME = '{table_name}')) BEGIN DROP TABLE {schema_table_name} END"#, table_name = table_name, schema_table_name = schema_table_name); log::info!("query {:?}", query); client.execute(query, &[]).await?; // 原代码参数冗余,SQL无占位符需传空数组 Ok(()) }
方法2:指定具体类型
如果明确知道Client的底层流是Compat<TcpStream>,可以直接写死类型:
use tiberius::compat::Compat; use tokio::net::TcpStream; async fn drop_table(&self, client: &mut Client<Compat<TcpStream>>) -> Result<(), AuthoritiesError> { // 函数体同方法1 }
错误原因
你之前的写法错误在于:TokioAsyncWriteCompatExt是一个trait,并非具体类型,不能直接作为Client<S>的泛型参数。Client<S>要求S是实现了AsyncRead + AsyncWrite + Unpin + Send的具体类型,而TokioAsyncWriteCompatExt::compat_write(tcp)返回的实际类型是Compat<TcpStream>,这才是符合约束的具体类型。
另外注意:原代码中client.execute的第二个参数是冗余的——SQL语句里没有使用参数占位符(如@p1),必须传空数组&[],否则会触发参数不匹配的运行时错误。
内容的提问来源于stack exchange,提问作者adviner
相关产品推荐
相关产品推荐

