Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chaining functions in Go?

Tags:

go

I tried doing this:

package main

import (
    "fmt"
    "strings"
)

type String string


func (s *String) tolower() String {
    *s = String(strings.ToLower(string(*s)))
    return *s
}

func (s *String) toupper() String {
    *s = String(strings.ToUpper(string(*s)))
    return *s
}

func main() {
    var s String = "ASDF"
    (s.tolower()).toupper() // this fails
    // s.toupper();s.tolower(); // this works
    // s.tolower().toupper() // this fails too
    fmt.Println(s)
}

But I got these errors:

prog.go:30: cannot call pointer method on s.tolower()
prog.go:30: cannot take the address of s.tolower()

Program exited.

Why can't I make this chain work?

like image 622
Derek Avatar asked Aug 09 '13 17:08

Derek


People also ask

What is chaining in programming?

Method chaining, also known as named parameter idiom, is a common syntax for invoking multiple method calls in object-oriented programming languages. Each method returns an object, allowing the calls to be chained together in a single statement without requiring variables to store the intermediate results.

What is method chaining in C#?

Method chaining is a technique in which methods are called on a sequence to form a chain and each of these methods return an instance of a class. These methods can then be chained together so that they form a single statement. A fluent interface is an object-oriented API that depends largely on method chaining.

What is method chaining in JavaScript?

Method chaining, or simply chaining, in JavaScript can be defined as when one or more sequential methods get invoked from an object without the introduction of unnecessary variables. The sole purpose of chaining is to make our code more readable and reduce the redundancy within.

Can you chain functions in Python?

Chaining functions is a common functional development pattern that is pretty difficult on Python. Usually, we need to pass some data through a pipeline, process or series of functions in order to get a specific output.


2 Answers

This works:

package main

import (
    "fmt"
    "strings"
)

type String string


func (s *String) tolower() *String {
    *s = String(strings.ToLower(string(*s)))
    return s
}

func (s *String) toupper() *String {
    *s = String(strings.ToUpper(string(*s)))
    return s
}

func main() {
    var s String = "ASDF"
    (s.tolower()).toupper()
    s.toupper();
    s.tolower();
    s.tolower().toupper()
    fmt.Println(s)
}

Your return type is of String, for functions defined on pointers to String. It wouldn't make sense to be able to chain them.

like image 154
Seth Hoenig Avatar answered Oct 06 '22 00:10

Seth Hoenig


tolower() and toupper() have pointer-to-String as the receivers, but they are returning String (not pointer-to-String).

You can fix this by changing one or the other.

e.g. change the signature of the function to either:

func (s *String) toupper() *String

or

func (s String) toupper() String

(see: http://play.golang.org/p/FaCD8AQtIX)

like image 25
mrjones Avatar answered Oct 06 '22 00:10

mrjones