Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Polymorphism in Go - does it exist?

Tags:

go

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?

like image 802
user3526096 Avatar asked Apr 22 '14 06:04

user3526096


People also ask

Does Go have polymorphism?

Golang is a light-Object Oriented language and supports polymorphism through interfaces only.

What is Golang composition?

Composition is a method employed to write re-usable segments of code. It is achieved when objects are made up of other smaller objects with particular behaviors, in other words, Larger objects with a wider functionality are embedded with smaller objects with specific behaviors.

How do you define an interface in Golang?

Go language interfaces are different from other languages. In Go language, the interface is a custom type that is used to specify a set of one or more method signatures and the interface is abstract, so you are not allowed to create an instance of the interface.


2 Answers

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())
}
like image 75
Nick Craig-Wood Avatar answered Sep 22 '22 02:09

Nick Craig-Wood


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")
}
like image 24
Everton Avatar answered Sep 19 '22 02:09

Everton