intro to go

&& generics

polymorphism

ducktaping

ducktyping

class Duck:
  def walk():
    print("walking like a duck")
    
  def quack():
    print("quacking like a duck")
    
class Dog:
  def walk()
  	print("walking like a dog")
    
for duck in [Duck(), Dog()]:
  duck.walk() and duck.quack()
  
# walking like a duck
# quacking like a duck
# walking like a dog
# AttributeError: 'Dog' object has no attribute 'quack'

python example

abstract base class

class BaseDuck:
  def walk():
    raise NotImplementedError("cannot walk yet")
    
  def quack():
    raise NotImplementedError("cannot quack yet")
    
class Duck(BaseDuck):
  def walk()
  	print("walking like a dog")
    
duck = Duck()
duck.walk()
duck.quack()
  
# walking like a duck
# NotImplementedError: cannot quack yet

python example

interface


interface Duck {
	public void walk();
	public void quack();
}

class Goose implements Duck {
	public void walk() {
    	System.out.println("walking like a duck")
    }
	public void quack() {
    	System.out.println("quacking like a duck")
    }
}

java example

type vs class

any ideas how to implement this feature?

new interface

new class

go has no classes

type vs class

pros:

  • defines functions and their signatures
  • independent from original
  • allows access underlying type

interface in go

cons:

  • limited to composite types
  • easy to abuse
  • adds complexity to code

interface


type Duck interface {
	Walk()
	Quack()
}

go example

type Goose struct {}

func (g *Goose) Walk() {
	fmt.Println("walking as a duck")
}

func (g *Goose) Quack() {
	fmt.Println("quacking as a duck")
}

interface

func main() {
	goose := &Goose{}
	DoDuckStuff(goose)
}

/* Output:
walking as a duck
quacking as a duck
*/

go example

empty interface

type Anything interface {}

func AnythingIsOK(a Anything) {
	fmt.Println(a)
}

generics


func GenericFunction[T any](something T) {
	// do something with something
}

// you need to "instantiate" function before using, e.g.
func main() {
	name = "Duck"
	GenericFunction[string](name)
}

generics

type GenericType[T any] struct {
	value T
}

// you need to "instantiate" struct before using, e.g.
func main() {
	genericType := GenericType[float64](0)
}

generics

type GenericType[T any] struct {}

type constraints

type GenericType[T comparable] struct {}
type GenericType[T int32 | float32 ] struct {}
type GenericType[T ~int32 | ~float32 ] struct {}
type GenericTypeAllowed interface {
	 ~int32 | ~float32
}

type GenericType[T GenericTypeAllowed] struct {}

Get in touch

Vachagan Gratian

Made with Slides.com