#From or Into trait?

1 messages ยท Page 1 of 1 (latest)

cold estuary
#
    pub fn name<T: Into<String>>(&mut self, name: T) -> &mut Self {
        self.name = name.into().clone();
        self
    }

What I want is some way to have &str, &String enter in one fn and change a struct field called name.
Easiest way to do so I found was to implement Into, but reading documentation it says I should use From.
Here is the part I got stuck on, why should I not use Into?

I am quite new and the language they used went bit over my head and wondered if someone could help me understand and maybe implement the best/correct way of doing this ๐Ÿ™‚

sonic grail
#

There was similar discussion on this topic in another thread recently, but you should require &str, and call to_owned(), if you're always going to allocate owned an owned string.

If you want to allow users to pass in an owned value (String), or a borrowed one, which data will be copied from (e.g., &str, Cow<'a, str>, Box<str>), then Into or From would be appropriate (There's a standard implementation for Into for types which implement From, where calling into() just defers to calling from()...).

#

(Notable, in this case, you're creating an owned version with into() already, and then creating another with clone()...)

teal geyser
#

You should not take &str if you'll always to_owned it.

You should take String, and make the caller to_owned if they need to

#

This way, if they have a String they don't need anymore, they can pass it to you zero-copy

sonic grail
#

A good case for Into as well,

cold estuary
#

If it helps, my background is Java from school and wanted to start learning rust.
So in my mind I wanted to make a object called Artist with some fields looking like hits:

pub struct Artist {
    name: String,
    date_of_birth: String,
    city: String,
    country: String,
}

Should this fields be String or &str?

teal geyser
#

As a rule of thumb, structs want to be owned

#

There are exceptions, but they're usually more advanced

cold estuary
#

Since the rule of thum is to own, then I guess the correct one would be Strings

teal geyser
#

&str means that your struct can only exist while something else does to own the data. Good for a view, for example, bad for many other uses

sonic grail
#

&str is like Java's strings, where the value is immutable, and can only be read from, meaning if you want modify the contents, you'll need to make your own copy.

teal geyser
#

With the difference that Java's strings don't need another string to exist to borrow from it

sonic grail
#

Yeah, Box<str> would be the most like Java's strings...

cold estuary
#

Right right, since I am used to multible constructers where you can change the amount of parameters rust have turned this a bit upside down on me.
I did found a blog that did a interssting thing https://tshi.page/dev/rust/constructors-of-rust-structs/

So I though if I made function for all the fields to get input it would work smart. But I want to be more dynamic and maby take in both &str, &String and string and output Self that have changed

teal geyser
#

Honestly I usually just take the type I need, and tell the caller to convert themselves

sonic grail
#

Less chance of the caller shooting themselves in the foot...

teal geyser
# cold estuary do you have a example?
pub fn set_name(&mut self, name: String) -> &mut Self {
  self.name = name;
  self
}
```call as `.set_name(string)`, or `.set_name(str.to_owned())`, or `.set_name(thing.into())`, or anything else, based on your needs
cold estuary
#

this is good! can you have fn with same name but diffrent parameters? from what I tested it did not work, but I could have implemented it wrong

sonic grail
sonic grail
teal geyser
sonic grail
#

Let the caller decide how to produce the type you require,

cold estuary
#

when you say caller, is that the fn set_name in this case?

hybrid ice
#

Into & From are interchangable

teal geyser
#

If you need to emulate multiple constructors, usually you'd do something like Vec's example: it has new, with_capacity, with_capacity_in, and new_in.

If the combinatorial explosion gets bad, you'd make a separate builder type, like OpenOptions is for File

sonic grail
cold estuary
#

this post, should I do something with it or does it close automatically?