Tips for Golfing in Go

25

3

What general tips do you have for golfing in Go? I'm new to Code Golfing and looking for ideas that can be applied to code golf problems in general that are at least somewhat specific to Go.

Please keep to one tip per answer.

Sheharyar

Posted 2014-11-25T09:49:17.570

Reputation: 651

@Optimizer I used to – cat – 2016-03-16T01:58:10.273

3Should rename the title to "Tips for Go-lfing" – Uriel – 2017-09-05T18:02:46.623

3We might want to create the Go tag, but then, is Go even being used for golfing here ? – Optimizer – 2014-11-25T09:51:40.917

Answers

14

Inspired by @EMBLEM's answer here.

You can put a package's functions in the global namespace when you import them like so:

package main

import ."fmt"

func main() {
    Printf("Hello World!")
}

George Gibson

Posted 2014-11-25T09:49:17.570

Reputation: 2 369

10

You can name packages whatever you like when you import them.

package main

import f "fmt"

func main() {
    f.Printf("Hello World\n")
}

Learned this here.

EMBLEM

Posted 2014-11-25T09:49:17.570

Reputation: 2 179

3You can also do import ."fmt" and then Println and the rest of fmt's functions are in the global namespace. Also, you don't need semicolons. Ever, unless you have multiple statements on a line – cat – 2016-03-16T01:59:13.687

1

Note that in Golang, braces must go on the same line, because of automatic semicolon insertion. More info: https://golang.org/doc/faq#semicolons.

– cat – 2016-03-22T22:41:17.840

8

Named return values can save a few bytes. For example:

func x()string{
r:="" //Do stuff
return r}

You can save 3 bytes with

func x()(r string){
//Do stuff
return}

It's more useful if you need to declare multiple variables at the start of your function.

EMBLEM

Posted 2014-11-25T09:49:17.570

Reputation: 2 179

7

If you need to compare many different values to a single one, it may be more space-efficient to use a switch with a single case.

if x==1||x==2||x==3||x==4{}
switch x{case 1,2,3,4:}

EMBLEM

Posted 2014-11-25T09:49:17.570

Reputation: 2 179

2

Go compiler has predefined print and println functions that don't require importing fmt, so instead of this.

package main
import."fmt"
func main(){Printf(`Hello World
`)}

You can write this.

package main
func main(){print(`Hello World
`)}

Note that this outputs to STDERR.

Konrad Borowski

Posted 2014-11-25T09:49:17.570

Reputation: 11 185

2

Declaring Multiple Variables:

i,s:=0,""

var(i int;s string)

Int From String Conversion: (limited but sometimes helpful)

n:=byte("9"[0])-48 // actual type is uint8

n,_:=strconv.Atoi("9")

And Vice Versa

s:=string(9+48)

s:=strconv.Itoa(9)

Justin Powell

Posted 2014-11-25T09:49:17.570

Reputation: 41

fmt.Sprint is likely to save bytes over strconv.Atoi, because you've likely imported fmt already. – EMBLEM – 2016-09-29T18:54:13.343

@EMBLEM I think strconv was there just to show what the golf-code would be in normal code. – Benny Jobigan – 2019-08-05T14:01:56.680

1

Go has different operator precedence for bit operations, <<, >>, &, etc. usually have lower precedence than + and - in most languages, but in Go they have the same precedence as * and /.

Precedence    Operator
5             *  /  %  <<  >>  &  &^
4             +  -  |  ^
3             ==  !=  <  <=  >  >=
2             &&
1             ||

This could be used to save some parentheses.

Most languages:

(a&b)*c

Go:

a&b*c

JayXon

Posted 2014-11-25T09:49:17.570

Reputation: 159

1

A lot of stuff in the for range loop is optional.

Standard version:

for i,v:=range a{
// Do stuff
}

If i, v has already been defined and can be overwritten:

for i,v=range a{
// Do stuff
}

If you don't care about value:

for i:=range a{
// Do stuff
}

If you don't care about value and i has already been defined:

for i=range a{
// Do stuff
}

If you don't care about index or value:

for range a{
// Do stuff
}

If you want an infinite loop:

for{
// Do stuff
}

JayXon

Posted 2014-11-25T09:49:17.570

Reputation: 159

1

Need a string to contain a newline? Don't write \n, create a raw string with backquotes and put a literal newline in it.

s:="\n" // 7 bytes
s:=`
` // 6 bytes

Purple P

Posted 2014-11-25T09:49:17.570

Reputation: 919

0

Make full use of Go's first-class functions by assigning long library function names to one-letter variables.

import."strings"
r:=Replace

Purple P

Posted 2014-11-25T09:49:17.570

Reputation: 919

0

You can put any number of opening braces on one line, but a line that contains opening braces may contain at most one closing brace.

Correct:

func main(){if true{switch{case 1==1:for{break
}}}}

Also correct:

func main(){if true{switch{case 1==1:for{break}
}}}

Also correct:

func main(){if true{switch{case 1==1:for{
break}}}}

Incorrect:

func main() {
    if true{for{break}}
}

EMBLEM

Posted 2014-11-25T09:49:17.570

Reputation: 2 179