Hacker News new | past | comments | ask | show | jobs | submit login

For what it's worth, String in Rust is similar to StringBuffer in other languages. You can append to a String; you can't append to a slice, which always represents a fixed view.

A slice has storage that is borrowed from somewhere else, but it itself does not have its own storage.

When you type `"foo"`, you are creating "static" storage (in the binary) and the slice is borrowed from that fixed-position location in memory.

Mostly, your functions produce Strings and consume slices.




But shouldn't they (String and slice) have some common super type to make this all easy to use?


I don't think a common ancestor is how you want to do this. Instead, I'd encapsulate the common behavior in a trait (a.k.a. an interface, in other languages), and then write functions that accept any parameters that implement that trait. In Rust, you can do this even on "built-in" types like strings. For an example, see the `print_me` function below, which operates on both string types using a trait that I've defined myself.

  trait WhatIsThis {
      fn what_is_this(self);
  }

  impl WhatIsThis for String {
      fn what_is_this(self) {
          println!("'{:s}' is a string!", self);
      }
  }

  impl WhatIsThis for &'static str {
      fn what_is_this(self) {
          println!("'{:s}' is a string slice!", self);
      }
  }

  fn print_me<T>(me: T) where T: WhatIsThis {
      me.what_is_this();
  }

  fn main() {
      print_me("Blah blah blah");
      print_me("Yada yada yada".to_string());
  }


And I expect virtually all of the methods on slice to be available on String before long. I think it's a bug that this isn't the case today.

It's already possible to have a function take "either a String or slice" generically:

    def print_me<T>(me: T) where T: Str {
        println!("I am '{:s}'", me.as_slice());
    }
The overall ergonomics of this (or at least, the well-documented idioms) will certainly improve in the coming months.



Yes. It's a design bug that String and slice don't share a common trait and that `.as_slice()` is common simply to use slice methods.

I expect that to be fixed before 1.0.


At least you can now do: foo[].some_slice_method()


I think this is an anti-pattern. I'm not a fan of the slicing syntax in general, which seems to exist only to paper over the missing traits that wycats mentions.


We will almost certainly just have `Deref<str> for String` and so autoderef will handle `some_string.some_slice_method()` correctly.


Will we be able to kill the slicing syntax, then? :)


Slicing syntax is about being able to do stuff like string[1:3] AFAIK, so I hope it won't get killed.


Also, the location of storage is slightly more visible (in general) in Rust than in other languages.

I have personally found this to be pretty clarifying, because as much a we may like to abstract over it, the location of storage often worms its way into the programming model even in HLLs.


Indeed. I feel like learning Rust has helped me grok C and Java much more, because the different forms of allocation is much are visible.


And that indeed is the real distinction between what Rust has and what other languages tend to have—the fact that &str doesn’t have its own storage. The equivalent to string types in other languages would be more like SendStr.

That functions produce Strings and consume slices is a good way of expressing it.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: