Victory
Victory

Reputation: 5890

rust - std::string::String as a byte string (i.e. b"foo" or deprecated bytes!("foo"))

I see that

let s = String::from_str("hello");
let bytes = s.into_bytes();
assert_eq!(bytes, vec![104, 101, 108, 108, 111]);

but what i would like to do is have

assert_eq!(s.something(), b"hello");

where .something() is just a placeholder, it might be something(s) or similar.

I am doing this so i can use strings with

fn foo(mut stream: BufferedStream<TcpStream>, str: String) {
   stream.write(str.something());
}

Upvotes: 11

Views: 9845

Answers (3)

ytll21
ytll21

Reputation: 860

Try it:

  let bytes = vec![104, 101, 108, 108, 111];
  assert_eq!(String::from_utf8(bytes.to_vec()).unwrap(), "hello");

Upvotes: 1

Vladimir Matveev
Vladimir Matveev

Reputation: 127761

First of all, you better write this:

fn foo(mut stream: BufferedStream<TcpStream>, s: String) {
   stream.write(s.something());
}

as this:

fn foo(mut stream: BufferedStream<TcpStream>, s: &str) {
   stream.write(s.something());
}

As a rule of thumb, try to use slices (&str for String) first, and if it does not work because of ownership, use String.

Second, the method you're looking for is called as_bytes():

fn foo(mut stream: BufferedStream<TcpStream>, s: &str) {
   stream.write(s.as_bytes());
}

There is no need to convert String to Vec<u8> first.

Upvotes: 5

McPherrinM
McPherrinM

Reputation: 4594

The .something() you want is called .as_slice(). Generally the word for a &[T] in rust is a slice, and the naming convention to cheaply borrow a type as another (in this case, from a Vec<T>) is .as_foo(). In this new comparison, you are comparing &[u8], instead of allocating a new Vec to compare. This should be much more efficient as well as more readable, since no allocation is needed.

    assert_eq!(bytes.as_slice(), b"hello");

Upvotes: 9

Related Questions