Go vs. Java: 15 main differences

yourbasic.org/golang

The following Java code, adapted from Effective Java, implements an immutable class representing a complex number.

public final class Complex {
    private final double re;
    private final double im;

    public Complex(double re, double im) {
        if (Double.isNaN(re) || Double.isNaN(im)) {
            throw new ArithmeticException();
        }
        this.re = re;
        this.im = im;
    }

    public double realPart()      { return re; }
    public double imaginaryPart() { return im; }

    public Complex add(Complex c) {
        return new Complex(re + c.re, im + c.im);
    }

    @Override public boolean equals(Object o) {
        if (o == this)
            return true;
        if (!(o instanceof Complex))
            return false;
        Complex c = (Complex) o;
        return Double.compare(re, c.re) == 0 &&
               Double.compare(im, c.im) == 0;
    }

    @Override public int hashCode() {
        int result = 17 + Double.hashCode(re);
        result = 31 * result + Double.hashCode(im);
        return result;
    }

    @Override public String toString() {
        return "(" + re + (im < 0 ? "" : "+") + im + "i)";
    }

    public static void main(String[] args) {
        Complex z = new Complex(1, 2);
        System.out.println(z.add(z));
    }
}

The same program written in idiomatic Go would consist of two separate packages.

package complex

import (
    "fmt"
    "math"
)

type Complex struct {
    re, im float64
}

func New(re, im float64) Complex {
    if math.IsNaN(re) || math.IsNaN(im) {
        panic("NaN")
    }
    return Complex{re, im}
}

func (c Complex) Real() float64 { return c.re }
func (c Complex) Imag() float64 { return c.im }

func (c Complex) Add(d Complex) Complex {
    return New(c.re+d.re, c.im+d.im)
}

func (c Complex) String() string {
    if c.im < 0 {
        return fmt.Sprintf("(%g%gi)", c.re, c.im)
    }
    return fmt.Sprintf("(%g+%gi)", c.re, c.im)
}
package main

import (
    "complex"
    "fmt"
)

func main() {
    z := complex.New(1, 2)
    fmt.Println(z.Add(z))
}

Note that in this case Go uses struct values where Java uses references to objects. Also, the equality and hash code methods are omitted since Go already defines equality for structs with comparable fields.

Main differences

Built-in types

Pointers and references

Error handling

Object-oriented programming

Functional programming

Concurrency

Omitted features

Complex numbers

Strangely enough, Go has built-in support for complex numbers.

z := 1+2i
fmt.Println(z + z)

It’s the least used feature of the language. By far.

Further reading

This Java to Go in-depth tutorial is in­tended to help Java deve­lopers come up to speed quickly with Go.

Share this page: