从Rust

时间:2016-10-01 05:08:46

标签: vector rust hashset

我想从HashSet<u8>建立一个Vec<u8>。我想这样做

  1. 在一行代码中,
  2. 仅复制一次数据,
  3. 仅使用2n内存,
  4. 但我唯一可以编译的就是这段..垃圾,我认为它会复制数据两次并使用3n内存。

    fn vec_to_set(vec: Vec<u8>) -> HashSet<u8> {
        let mut victim = vec.clone();
        let x: HashSet<u8> = victim.drain(..).collect();
        return x;
    }
    

    我希望写一些简单的东西,比如:

    fn vec_to_set(vec: Vec<u8>) -> HashSet<u8> {
        return HashSet::from_iter(vec.iter());
    }
    

    但不会编译:

    error[E0308]: mismatched types
     --> <anon>:5:12
      |
    5 |     return HashSet::from_iter(vec.iter());
      |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected u8, found &u8
      |
      = note: expected type `std::collections::HashSet<u8>`
      = note:    found type `std::collections::HashSet<&u8, _>`
    

    ..我并不是真的理解错误信息,可能是因为我需要RTFM。

3 个答案:

答案 0 :(得分:20)

以下应该可以很好地运作;它符合您的要求:

use std::collections::HashSet;
use std::iter::FromIterator;

fn vec_to_set(vec: Vec<u8>) -> HashSet<u8> {
    HashSet::from_iter(vec)
}

from_iter()适用于实现IntoIterator的类型,因此Vec参数就足够了。

补充说明:

  • 您不需要明确return功能结果;你只需要在其正文的最后一个表达式中省略分号

  • 我不确定您使用的是哪个版本的Rust,但目前的稳定版(1.12)to_iter()并不存在

答案 1 :(得分:20)

因为操作不需要使用向量¹,我认为不应该使用它。这只会导致程序中其他地方的额外复制:

 private void uploadFile(String filePath, String fileName) {
        Log.e(TAG, "File filename:----------->uploadFile "+filePath+", "+fileName);
        InputStream inputStream;


        try {
            inputStream = new FileInputStream(new File(filePath));
            Log.e(TAG, "File inputStream:-----------> "+inputStream);
            byte[] data;
            try {
                data = IOUtils.toByteArray(inputStream);
                Log.e(TAG, "File data:-----------> "+data);
                HttpClient httpClient = new DefaultHttpClient();
                HttpPost httpPost = new HttpPost("Your URL");
                Log.e(TAG, "File httpPost:-----------> "+httpPost);
                InputStreamBody inputStreamBody = new InputStreamBody(new ByteArrayInputStream(data), fileName);

                Log.e(TAG, "File inputStreamBody:-----------> "+inputStreamBody);
                MultipartEntity multipartEntity = new MultipartEntity();

                multipartEntity.addPart("fileContent0", inputStreamBody);
                multipartEntity.addPart("id", new StringBody("331"));
                multipartEntity.addPart("fileCount",  new StringBody("1"));
                multipartEntity.addPart("fileType", new StringBody("SAMPLE"));
                multipartEntity.addPart("platform", new StringBody("Android"));
                multipartEntity.addPart("externalID", new StringBody(""));
                httpPost.addHeader("Authorization","");
                Log.e(TAG, "File multipartEntity:-----------> "+multipartEntity);
                httpPost.setEntity(multipartEntity);

                HttpResponse httpResponse = httpClient.execute(httpPost);

                Log.e(TAG, "File httpResponse:----------->httpResponse "+httpResponse.getStatusLine());

                BufferedReader rd = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent()));

                StringBuffer result = new StringBuffer();
                String line = "";
                while ((line = rd.readLine()) != null) {
                    result.append(line);
                }

                JSONObject o = new JSONObject(result.toString());


                Log.e("oooooo","ooooooo------------------>"+o);
                // Handle response back from script.
                if (httpResponse != null) {
                    Log.e(TAG, "File httpResponse111:----------->httpResponse11 "+httpResponse);
                } else { // Error, no response.

                }
            } catch (IOException e) {
                Log.e("error","error--------->"+e);
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }
    }
}

将其称为use std::collections::HashSet; use std::iter::FromIterator; fn hashset(data: &[u8]) -> HashSet<u8> { HashSet::from_iter(data.iter().cloned()) } ,其中hashset(&v)v或其他强制切片的内容。

当然有更多的方式来写这个,通用和所有这些,但这个答案只是介绍我想要关注的事情。

¹这是基于元素类型Vec<u8>u8,即它没有所有权语义。

答案 2 :(得分:1)

移动数据所有权

let vec: Vec<usize> = vec![1, 2, 3, 4];
let hash_set: HashSet<usize> = vec.into_iter().collect();

克隆数据

let vec: Vec<usize> = vec![1, 2, 3, 4];
let hash_set: HashSet<usize> = vec.iter().cloned().collect();