Skip to content

Instantly share code, notes, and snippets.

@bradfitz
Created July 13, 2011 16:05
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bradfitz/1080626 to your computer and use it in GitHub Desktop.
Save bradfitz/1080626 to your computer and use it in GitHub Desktop.
Optional parameters in Go hack
// A cute hack demonstrating one (weird?) way of doing optional
// parameters in Go.
//
// Please don't write code like this. It is fun code, though.
//
// Output: (see it live at golang.org)
//
// I like cheese.
// Do you like cheese too?
// I DO!
// ***** Cheese party! *****
//
// My apologies,
// <bradfitz@golang.org>
package main
import (
"fmt"
"strings"
"sync"
)
func main() {
s := Sentence("I like cheese")()
fmt.Println(s)
s = Sentence("Do you like cheese too").Question(true)()
fmt.Println(s)
s = Sentence("I do").Exclamation(true).AllCaps(true)()
fmt.Println(s)
s = Sentence("Cheese party").Exclamation(true).SurroundWith("*", 5)()
fmt.Println(s)
}
type SentenceFunc func() string
func Sentence(base string) SentenceFunc {
a := &sentenceArgs{base: base}
var f SentenceFunc
f = SentenceFunc(func() string {
argsLock.Lock()
defer argsLock.Unlock()
args[f] = nil, false
return a.result()
})
argsLock.Lock()
defer argsLock.Unlock()
args[f] = a
return f
}
type sentenceArgs struct {
base string
q, bang bool
caps bool
surround string
surroundN int
}
func (a *sentenceArgs) result() string {
s := a.base
if a.q { s += "?" }
if a.bang { s += "!" }
if !a.bang && !a.q { s += "." }
if a.caps { s = strings.ToUpper(s) }
if a.surround != "" {
rp := strings.Repeat(a.surround, a.surroundN)
s = fmt.Sprintf("%s %s %s", rp, s, rp)
}
return s
}
var argsLock sync.Mutex
var args = make(map[SentenceFunc]*sentenceArgs)
func (f SentenceFunc) args() *sentenceArgs {
argsLock.Lock()
defer argsLock.Unlock()
return args[f]
}
func (f SentenceFunc) Exclamation(v bool) SentenceFunc {
f.args().bang = v
return f
}
func (f SentenceFunc) Question(v bool) SentenceFunc {
f.args().q = v
return f
}
func (f SentenceFunc) AllCaps(v bool) SentenceFunc {
f.args().caps = v
return f
}
func (f SentenceFunc) SurroundWith(s string, n int) SentenceFunc {
args := f.args()
args.surround, args.surroundN = s, n
return f
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment