type options struct {
zero rune
}
func (opts *options) isDigit(r rune) bool {
r -= opts.zero
return r >= 0 && r <= 9
}
// opts escapes to heap
func index1(s string, opts options) int {
return strings.IndexFunc(s, opts.isDigit)
}
// opts does not escape to heap
func index2(s string, opts options) int {
return strings.IndexFunc(s, func(r rune) bool {
return opts.isDigit(r)
})
}
Basically, in your index1, the opts.isDigit passed to IndexFunc is syntactic sugar for (&opts).isDigit -> then the compiler needs to move opts on the heap.
For your index2 function question, I think it's because Go maintains the variables from a parent function that are referred in an enclosed function (closure) for as long as both are alive.
I'm guessing that opts.IsDigit(r) is alive and kicking till it returns.
$ go build -gcflags="-l -m=2"
./escape.go:20:10: <S> capturing by ref: opts (addr=true assign=false width=4)
./escape.go:9:38: (*options).isDigit opts does not escape
./escape.go:15:34: opts escapes to heap
./escape.go:15:34: from opts.isDigit (call part) at ./escape.go:15:34
./escape.go:14:37: moved to heap: opts
./escape.go:14:37: index1 s does not escape
./escape.go:15:34: index1 opts.isDigit does not escape
./escape.go:18:37: index2 s does not escape
./escape.go:19:30: index2 func literal does not escape
./escape.go:20:14: index2.func1 opts does not escape
Basically, in your index1, the opts.isDigit passed to IndexFunc is syntactic sugar for (&opts).isDigit -> then the compiler needs to move opts on the heap.
For your index2 function question, I think it's because Go maintains the variables from a parent function that are referred in an enclosed function (closure) for as long as both are alive.
I'm guessing that opts.IsDigit(r) is alive and kicking till it returns.
--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/x9ZV-_XVaUk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.
The expression x is evaluated and saved during the evaluation of the method value; the saved copy is then used as the receiver in any calls, which may be executed later.
// isDigit called directly: opts does not escape to heap
func isDigit1(r rune, opts options) bool {
return opts.isDigit(r)
}
// isDigit called via method value: opts escapes to heap
func isDigit2(r rune, opts options) bool {
f := opts.isDigit
return f(r)
}
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
func parent() bool {
var opts options
return noEscape('0', &opts)
}