At runtime, is there a way to tell the structure's symbol name, of which a bound method offered a satisfactory implementation of a function type?

108 views
Skip to first unread message

Houzuo Guo

unread,
Jun 9, 2019, 12:48:07 PM6/9/19
to golang-nuts
Hello fellow gophers.

Given a function type: type Fun func()

And two structure methods that satisfy the function type:

type Alpha struct {
}
func (a Alpha) funA() {
}

type Beta struct {
}
func (b Beta) funB() {
}

At runtime, is there a way to tell whether a non-nil `var f Fun` is assigned to an arbitrary instance of structure Alpha, or Beta? Can reflection help in this case?

Thanks!

Kind regards,
Howard

Ian Lance Taylor

unread,
Jun 10, 2019, 12:46:58 AM6/10/19
to Houzuo Guo, golang-nuts
On Sun, Jun 9, 2019 at 9:48 AM Houzuo Guo <guoh...@gmail.com> wrote:
>
> Given a function type: type Fun func()
>
> And two structure methods that satisfy the function type:
>
> type Alpha struct {
> }
> func (a Alpha) funA() {
> }
>
> type Beta struct {
> }
> func (b Beta) funB() {
> }
>
> At runtime, is there a way to tell whether a non-nil `var f Fun` is assigned to an arbitrary instance of structure Alpha, or Beta? Can reflection help in this case?

I'm sorry, I don't understand your question. funA and funB are
methods. You can't assign to a method. And the structs have no
fields, so you can't assign to that either. So I'm not sure what you
mean.

That said, I suspect the answer to your real question is "no."

Ian

Houzuo Guo

unread,
Jun 10, 2019, 1:17:40 AM6/10/19
to golang-nuts
Thanks very much Ian - indeed I should have proof read the message. With the last paragraph, I wished to ask for a way to tell a non-nil ` var f Fun` is assigned to `funA` of any instance of structure Alpha, or `funB` of any instance of structure Beta - without performing equality comparison between the instances' method and the `f` variable.

Take an example - suppose there are:
- var a1,a2,a3,a4,a5 Alpha
- var b1,b2,b3,b4,b5 Beta
- var f Fun

And that `f` is assigned to any of:
- a1.funA, a2.funA ...
- b1.funB, b2.funB ...

Without performing equality check (f == a1.funA || f == a2.funA || f == a3.funA ...), construct a test condition that evaluates to true only if `f` is assigned to `funA` of any instance of `Alpha`.

Kind regards,
Howard

Ian Lance Taylor

unread,
Jun 10, 2019, 6:10:39 PM6/10/19
to Houzuo Guo, golang-nuts
On Sun, Jun 9, 2019 at 10:17 PM Houzuo Guo <guoh...@gmail.com> wrote:
>
> Thanks very much Ian - indeed I should have proof read the message. With the last paragraph, I wished to ask for a way to tell a non-nil ` var f Fun` is assigned to `funA` of any instance of structure Alpha, or `funB` of any instance of structure Beta - without performing equality comparison between the instances' method and the `f` variable.
>
> Take an example - suppose there are:
> - var a1,a2,a3,a4,a5 Alpha
> - var b1,b2,b3,b4,b5 Beta
> - var f Fun
>
> And that `f` is assigned to any of:
> - a1.funA, a2.funA ...
> - b1.funB, b2.funB ...
>
> Without performing equality check (f == a1.funA || f == a2.funA || f == a3.funA ...), construct a test condition that evaluates to true only if `f` is assigned to `funA` of any instance of `Alpha`.

But in your code funA and funB are methods. You can't assign f to
a1.funA. You can't change a1.funA at all.

Can you show a small runnable example of what you are asking about?

Ian




> On Monday, 10 June 2019 07:46:58 UTC+3, Ian Lance Taylor wrote:
>>
>> On Sun, Jun 9, 2019 at 9:48 AM Houzuo Guo <guoh...@gmail.com> wrote:
>> >
>> > Given a function type: type Fun func()
>> >
>> > And two structure methods that satisfy the function type:
>> >
>> > type Alpha struct {
>> > }
>> > func (a Alpha) funA() {
>> > }
>> >
>> > type Beta struct {
>> > }
>> > func (b Beta) funB() {
>> > }
>> >
>> > At runtime, is there a way to tell whether a non-nil `var f Fun` is assigned to an arbitrary instance of structure Alpha, or Beta? Can reflection help in this case?
>>
>> I'm sorry, I don't understand your question. funA and funB are
>> methods. You can't assign to a method. And the structs have no
>> fields, so you can't assign to that either. So I'm not sure what you
>> mean.
>>
>> That said, I suspect the answer to your real question is "no."
>>
>> Ian
>
> --
> 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/f7a6221a-aada-4f3a-ab12-34d26f550e87%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Houzuo Guo

unread,
Jun 11, 2019, 1:23:51 AM6/11/19
to Ian Lance Taylor, golang-nuts
Hello Ian.

Here's a complete example constructed from the snippets:

-------------------------
package main

type Fun func()
type Alpha struct {
}
func (a Alpha) funA() {
}

type Beta struct {
}
func (b Beta) funB() {
}

var a1,a2,a3,a4,a5 Alpha
var b1,b2,b3,b4,b5 Beta
var f Fun

func main() {
f = a1.funA
f = b1.funB
// Challenge: construct an expression that evaluates to true only if f
is assigned to `funA` of any instance of `Alpha`
}
-------------------------
https://play.golang.org/p/HoGGR0NeLE2

Thanks!

Kind regards,
Howard

Ian Lance Taylor

unread,
Jun 11, 2019, 1:33:08 AM6/11/19
to Houzuo Guo, golang-nuts
On Mon, Jun 10, 2019 at 10:23 PM Houzuo Guo <guoh...@gmail.com> wrote:
>
> Here's a complete example constructed from the snippets:
>
> -------------------------
> package main
>
> type Fun func()
> type Alpha struct {
> }
> func (a Alpha) funA() {
> }
>
> type Beta struct {
> }
> func (b Beta) funB() {
> }
>
> var a1,a2,a3,a4,a5 Alpha
> var b1,b2,b3,b4,b5 Beta
> var f Fun
>
> func main() {
> f = a1.funA
> f = b1.funB
> // Challenge: construct an expression that evaluates to true only if f
> is assigned to `funA` of any instance of `Alpha`
> }
> -------------------------
> https://play.golang.org/p/HoGGR0NeLE2

Thanks. Your meaning of "is assigned to" is the reverse of mine.

There is no reliable way to determine that. Go does not permit the
comparison of function values, because Go makes no effort to ensure
that two functions that appear to be the same are necessarily equal.

You can get an approximate comparison by writing
reflect.ValueOf(f).Pointer() == reflect.ValueOf(a1.funA).Pointer()
but there are cases where that will fail.

Ian

Houzuo Guo

unread,
Jun 11, 2019, 1:36:52 AM6/11/19
to Ian Lance Taylor, golang-nuts
Thanks very much Ian!

Kind regards,
Howard
Reply all
Reply to author
Forward
0 new messages