6

I am trying to make something real simple on Go: to have an interface with getter and setter methods. And it seems setter methods are not allowed.

Given this code:

package main

import "fmt"

type MyInterfacer interface {
    Get() int
    Set(i int)
}

type MyStruct struct {
    data int
}

func (this MyStruct) Get() int {
    return this.data
}

func (this MyStruct) Set(i int) {
    this.data = i
}

func main() {
    s := MyStruct{123}
    fmt.Println(s.Get())

    s.Set(456)
    fmt.Println(s.Get())

    var mi MyInterfacer = s
    mi.Set(789)
    fmt.Println(mi.Get())
}

Set method does not work, because in func (this MyStruct) Set(i int), this MyStruct is not a pointer, and the changes are lost as soon at the function exits. But making it this *MyStruct would not compile. Is there any workaround?

Nick Craig-Wood
  • 52,955
  • 12
  • 126
  • 132
user3526096
  • 105
  • 1
  • 2

4 Answers4

8

Here is a corrected version of your code (playground). This isn't exactly Polymorphism, but the use of an interface is good Go style.

package main

import "fmt"

type MyInterfacer interface {
    Get() int
    Set(i int)
}

type MyStruct struct {
    data int
}

func (this *MyStruct) Get() int {
    return this.data
}

func (this *MyStruct) Set(i int) {
    this.data = i
}

func main() {
    s := &MyStruct{123}
    fmt.Println(s.Get())

    s.Set(456)
    fmt.Println(s.Get())

    var mi MyInterfacer = s
    mi.Set(789)
    fmt.Println(mi.Get())
}
Nick Craig-Wood
  • 52,955
  • 12
  • 126
  • 132
4

I once found this example of how to do polymorphism in Go:

http://play.golang.org/p/6Ip9scm4c3

package main

import "fmt"

type Talker interface {
        Talk(words string)
}

type Cat struct {
        name string
}

type Dog struct {
        name string
}

func (c *Cat) Talk(words string) {
        fmt.Printf("Cat " + c.name + " here: " + words + "\n")
}

func (d *Dog) Talk(words string) {
        fmt.Printf("Dog " + d.name + " here: " + words + "\n")
}

func main() {
        var t1, t2 Talker

        t1 = &Cat{"Kit"}
        t2 = &Dog{"Doug"}

        t1.Talk("meow")
        t2.Talk("woof")
}
Everton
  • 12,589
  • 9
  • 47
  • 59
2

To answer the question the in the title to post:

Go does not use classes, but provides many of the same features:

* message passing with methods
* automatic message delegation via embedding
* polymorphism via interfaces
* namespacing via exports

From: http://nathany.com/good/

Solving the code you supplied, I will leave to some more learned Gopher

Cleric
  • 3,167
  • 3
  • 23
  • 24
2

###AD HOC polymophism

Ad hoc polymorphism is a general way of polymorphism implementation for statically typed languages. Polymorphism in Go is ad hoc polymorphism which is very close to Bjarne's Stroustrup definition:

Polymorphism – providing a single interface to entities of different types.

Interfaces

Go interface is really powerful tool designed specially for polymorphism implementation. Interface is a type abstraction (sets of methods) which provides a way to specify the behavior of an object: if something can do this, then it can be used here. Back to Straustrup's polymorphism definition: it is possible to use objects of different types as a type of a common interface if they implement the interface.

Playground with an example.

Parametric polymorphism

Wiki:

A function or a data type can be written generically so that it can handle values identically without depending on their type.

This kind of polymorphism is more regular for dynamically typed languages like Python or Ruby but Go implements it too! Go uses type empty interface interface{} for this purpose.

Type interface{}

From Tour Of Go:

The interface type that specifies zero methods is known as the empty interface:

interface{} An empty interface may hold values of any type. Every type implements at least zero methods.

Empty interfaces are used by code that handles values of unknown type. For example, fmt.Print takes any number of arguments of type interface{}.

And it is possible to get particular type of an object with type assertion.

And again Tour Of Go:

A type assertion provides access to an interface value's underlying concrete value.

t := i.(T)

This statement asserts that the interface value i holds the concrete type T and assigns the underlying T value to the variable t.

There we have parametric polymorphism with static duck typing.

Zombo
  • 1
  • 62
  • 391
  • 407
I159
  • 29,741
  • 31
  • 97
  • 132