Assign method to custom types in Golang

0

I have a code where I need to perform several replaces and for this I did the following:

exemplo := "Olá, meu nome é xpto, na verdade xpto da silva xpto"
formated := strings.Replace(exemplo, "xpto", "Fulano")
formated := strings.Replace(formated, "Olá", "oi")

fmt.Println(formated)

To try to make it more "friendly" I decided to create a variable of type string that would allow me to use a chained "replace" method, which would look like this:

exemplo := "Olá, meu nome é xpto, na verdade xpto da silva xpto"
formated := custom(exemplo).replace("xpto", "fulano").replace("olá", "oi")

For this I did:

type custom string

func (c *custom) replace(old, new string) custom {
    content := string(*c)
    return custom(strings.Replace(content, old, new, -1))
}

func main() {
    text := custom("Olá, nome, Olá, nome")
    fmt.Println(text.replace("Olá", "oi").replace("nome", "nombre"))

}

When executing the code with only 1 replace it executes successfully, but if I try to chain another replace as in the example above I get the error that can not access the pointer nor the address of text.replace("Olá", "oi") , I believe this error is generated because when I return the "custom" in replace no memory address is assigned to it.

  

can not call pointer method on text.replace ("Hi", "hi")

     

can not take the address of text.replace ("Hello", "hi")

I have tried to assign the return of replace to a variable to generate a memory address:

func (c *custom) replace(old, new string) *custom {
    content := string(*c)
    formated := custom(strings.Replace(content, old, new, -1))

    return &formated
}

But in this way, Println in main will display the address, not the value.

How can I use the value returned from a function in a threaded method?

    
asked by anonymous 18.02.2018 / 17:25

1 answer

1

You can create a pointer, as follows:

func (c *custom) replace(old, new string) *custom {
    content := string(*c)
    r := custom(strings.Replace(content, old, new, -1))
    return &r
}

Then use it as:

func main() {
    text := custom("Olá, nome, Olá, nome")
    fmt.Println(*text.replace("Olá", "oi").replace("nome" ,"xx"))
}

This will work as expected, use * to retrieve the value, in print .

Another option is to just not use references / pointers:

func (c custom) replace(old, new string) custom {
    return custom(strings.Replace(string(c), old, new, -1))
}

func main() {
    text := custom("Olá, nome, Olá, nome")
    fmt.Println(text.replace("Olá", "oi").replace("nome" ,"xx"))
}

Try this at link

What's the difference between one and the other? Basically if you use (c *custom) you're saying that the input is a reference, not the value.

So, if you do:

func (c *custom) replace(old, new string) custom

You expect an entry as a reference, but it outputs the value itself. Golang tries to "auto-convert" (it uses the reference rather than the value itself), see that it works:

text := custom("Olá, nome, Olá, nome")
x := text.replace("Olá", "oi")
y := x.replace("nome", "nombre")

fmt.Println(y)

Variables are addressable, you can create the pointer, with &x . The problem is that in Golang you can not create pointers to anything, this is invalid:

fmt.Println( (&text.replace("Olá", "oi")).replace("nome", "nombre") )

Note that it gives the same error, even if you do:

fmt.Println( (&text.replace("Olá", "oi")) )

This is exactly what Go tries to do internally, and is the cause of the "can not take the address of text.replace (" Hello "," hi ")".

According to documentation in "Address Operator" you can only create variable, slice, and related references.

Already using c custom you expect the value itself, not its pointer, so it will work.

    
18.02.2018 / 19:25