var fn myHandler = func(){ fn }

瀏覽次數:66 次
跳到第一則未讀訊息

Gert

未讀,
2020年7月12日 下午2:11:172020/7/12
收件者:golang-nuts
https://play.golang.org/p/6xMgjr1IyFD

var fn myHandler
fn = func(w http.ResponseWriter, r *http.Request) {
  fn.GET(w, r)
}

Just wondering if it's possible somehow to write this in one line like so

var fn myHandler = func(w http.ResponseWriter, r *http.Request) {
  fn.GET(w, r)
}

and if that would break Go if it was allowed to do so?

Bakul Shah

未讀,
2020年7月12日 下午3:33:432020/7/12
收件者:Gert、golang-nuts
On Jul 12, 2020, at 11:11 AM, Gert <gert.c...@gmail.com> wrote:
>
> https://play.golang.org/p/6xMgjr1IyFD
>
> var fn myHandler
> fn = func(w http.ResponseWriter, r *http.Request) {
> fn.GET(w, r)
> }
>
> Just wondering if it's possible somehow to write this in one line like so
>
> var fn myHandler = func(w http.ResponseWriter, r *http.Request) {
> fn.GET(w, r)
> }

The issue is that fn's type can't be completely determined until
the RHS func is fully analyzed but for that to work fn must be
known! This is not a problem when a "const" function references
itself as in `func foo() { ... foo() ... }`.

Also note that the first definition won't do what you may be thinking
it does. The`fn.GET` call will be to the existing value of fn, not
the result of the assignment.

Gert

未讀,
2020年7月12日 下午4:06:362020/7/12
收件者:golang-nuts
On Sunday, July 12, 2020 at 9:33:43 PM UTC+2 ba...@iitbombay.org wrote:
The issue is that fn's type can't be completely determined until
the RHS func is fully analyzed but for that to work fn must be
known! This is not a problem when a "const" function references
itself as in `func foo() { ... foo() ... }`.

Also note that the first definition won't do what you may be thinking
it does. The`fn.GET` call will be to the existing value of fn, not
the result of the assignment.

Ok thanks 

Axel Wagner

未讀,
2020年7月12日 下午4:44:022020/7/12
收件者:Bakul Shah、Gert、golang-nuts
On Sun, Jul 12, 2020 at 9:33 PM Bakul Shah <ba...@iitbombay.org> wrote:
On Jul 12, 2020, at 11:11 AM, Gert <gert.c...@gmail.com> wrote:
>
> https://play.golang.org/p/6xMgjr1IyFD
>
> var fn myHandler
> fn = func(w http.ResponseWriter, r *http.Request) {
>   fn.GET(w, r)
> }
>
> Just wondering if it's possible somehow to write this in one line like so
>
> var fn myHandler = func(w http.ResponseWriter, r *http.Request) {
>   fn.GET(w, r)
> }

The issue is that fn's type can't be completely determined until
the RHS func is fully analyzed but for that to work fn must be
known!

Why? ISTM the type is mentioned twice - once as "myHandler" on the LHS and once in the signature on the RHS. And there isn't even a way to write down a function literal without mentioning the full type. On the surface, this seems like a relatively straightforward scoping issue, introduced by the fact that the scope of a variable declaration starts at the end of it's VarSpec, not the "=". Interestingly though, the initialization rules prevent this from working at the package-level, where this scoping problem doesn't exist: https://play.golang.org/p/IPMxtYETGsg

Also note that the first definition won't do what you may be thinking
it does. The`fn.GET` call will be to the existing value of fn, not
the result of the assignment.

No, it won't. The function-literal closes over `fn`, so it will use whatever is assigned at call-time.
I use this pattern all the time to define a recursive function without polluting the package-scope.


--
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.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/716C7D59-9F2B-4AAD-8560-79011359A96C%40iitbombay.org.

seank...@gmail.com

未讀,
2020年7月12日 下午5:06:372020/7/12
收件者:golang-nuts

Bakul Shah

未讀,
2020年7月12日 下午5:19:102020/7/12
收件者:Axel Wagner、Gert、golang-nuts
On Jul 12, 2020, at 1:43 PM, Axel Wagner <axel.wa...@googlemail.com> wrote:
>
>
>
> On Sun, Jul 12, 2020 at 9:33 PM Bakul Shah <ba...@iitbombay.org> wrote:
> On Jul 12, 2020, at 11:11 AM, Gert <gert.c...@gmail.com> wrote:
> >
> > https://play.golang.org/p/6xMgjr1IyFD
> >
> > var fn myHandler
> > fn = func(w http.ResponseWriter, r *http.Request) {
> > fn.GET(w, r)
> > }
> >
> > Just wondering if it's possible somehow to write this in one line like so
> >
> > var fn myHandler = func(w http.ResponseWriter, r *http.Request) {
> > fn.GET(w, r)
> > }
>
> The issue is that fn's type can't be completely determined until
> the RHS func is fully analyzed but for that to work fn must be
> known!
>
> Why? ISTM the type is mentioned twice - once as "myHandler" on the LHS and once in the signature on the RHS. And there isn't even a way to write down a function literal without mentioning the full type. On the surface, this seems like a relatively straightforward scoping issue, introduced by the fact that the scope of a variable declaration starts at the end of it's VarSpec, not the "=". Interestingly though, the initialization rules prevent this from working at the package-level, where this scoping problem doesn't exist: https://play.golang.org/p/IPMxtYETGsg

You're right.

>
> Also note that the first definition won't do what you may be thinking
> it does. The`fn.GET` call will be to the existing value of fn, not
> the result of the assignment.
>
> No, it won't. The function-literal closes over `fn`, so it will use whatever is assigned at call-time.
> https://play.golang.org/p/VCvCt8J8Zcw
> I use this pattern all the time to define a recursive function without polluting the package-scope.

Right again. What matters is the value of fn when the function is called,
not when it is defined. Clearly I wasn't thinking clearly.

Thanks for setting me straight. And apologies to Gert.
回覆所有人
回覆作者
轉寄
0 則新訊息