Rust编译器选择collection :: string而不是std :: string

nat*_*ore 0 string rust

我在弄清楚为什么rustc假设我要使用collection::string::String而不是时遇到了一些麻烦std::string::String

我没有直接使用它的声明,并且有特定的使用声明

这是我的条板箱根的简化版本:

extern crate serialize;
extern crate collections;

use std::str;
use std::string::String;
use std::io::{TcpListener, TcpStream};
use std::io::{Listener, Acceptor};
use self::serialize::json;
use self::serialize::json::Json;
use self::collections::tree_map::TreeMap;

use self::socket::Socket;
use self::socket::event::Event;
use self::socket::action::Action;
use self::socket::message::{Message, Text, Binary};
use self::server::Server;
use self::httpheader::{RequestHeader, ReturnHeader};
use self::socketmessenger::SocketMessenger;

pub mod socket;
pub mod server;
mod httpheader;
mod socketmessenger;
Run Code Online (Sandbox Code Playgroud)

这是我的mod抛出错误的顶部:

extern crate "rust-crypto" as rust_crypto;

use self::rust_crypto::digest::Digest;
use self::rust_crypto::sha1::Sha1;
use super::serialize::base64::{ToBase64, STANDARD};
use super::std::string::String;

pub struct RequestHeader {
    pub upgrade: String,
    pub connection: String,
    pub host: String,
    pub origin: String,
    pub pragma: String,
    pub cache_control: String,
    pub sec_websocket_key: String,
    pub sec_websocket_version: String,
    pub sec_websocket_extensions: String,
    pub user_agent: String
}
Run Code Online (Sandbox Code Playgroud)

编译器给我:

src/httpheader/mod.rs:156:25: 156:42 error: type `collections::string::String` does not implement any method in scope named `push_bytes`
src/httpheader/mod.rs:156             stringified.push_bytes(bytes);
Run Code Online (Sandbox Code Playgroud)

当我尝试像这样将字节推入String时:

unsafe {
    let bytes = self.sec_websocket_accept.as_bytes();
    stringified.push_bytes(bytes);
}
Run Code Online (Sandbox Code Playgroud)

我会假设我的位置String是from std::string::String,而不是collections::string::String因为我没有指定要String在collection crate中使用的任何位置。

谁能建议我为什么看到这种行为?在此先感谢您的帮助!

Vla*_*eev 5

Rust的概念为pub use,从模块重新导出标识符。例如,在这里:

pub mod a {
    pub use b::Struct;
}

pub mod b {
    pub struct Struct;
}
Run Code Online (Sandbox Code Playgroud)

您可以同时使用Structfrom a和from b

use a::Struct;
// or
use b::Struct;
Run Code Online (Sandbox Code Playgroud)

Rust标准库中经常使用此机制。特别std是,实际上很多功能是在其他包装箱中定义的,并且std为了方便起见将其重新导出。String,例如,是在collections板条箱中定义的,但是,它是按std::string模块重新导出的,更重要的是,它也是由再次导出的std::prelude,其内容会自动导入所有常规模块中。这意味着collections::string::Stringstd::string::String可以像一样访问,也就是String,因此您无需显式导入它。

但是,您的问题不是导入。String只是不包含 push_bytes()(为什么您首先认为它包含?)。这是有原因的。String保证是正确的UTF-8序列,因此将任意字节压入它是不安全的-您可以轻松地将无效的UTF-8字节序列压入,破坏了保证。

如果需要使用字节,则应使用Vec<u8>,这是一个通用的可增长字节缓冲区。当您完成推给它新的字节,如果你确信这些字节代表有效UTF-8,你可以使用String::from_utf8()静态方法(或者from_utf8_lossy(),或者from_utf16()/ from_utf16_lossy()如果你的输入是UTF-16)转换Vec<u8>String有效。