-
Notifications
You must be signed in to change notification settings - Fork 17.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Type func signatures and interface bindings #24996
Comments
Do you mean |
That's what I was looking for! whew I knew about the postfixed .(type) for type assertion but I didn't know there was a prefix of any form. Thanks! |
Ok, I seem to have finally 100% fixed the issue. I need to not use the Also, it appears that in the interface the signature for the function has to be public (initial capital) for this to work. Kinda makes sense since without public it's not able to export outside of the scope (I think). Ok, I have confirmed that this seems to be the correct way to do it (at least go vet is happy): type Bast struct {
...
isNull interface{}
...
}
func (b *Bast) isNull(d uint32) bool {
return d == 0
}
func NewBast() (b *Bast) {
...
b.isNull = (*Bast).isNull
...
}
// IsNull - tests if a value in the tree is null
func (b *Bast) IsNull(d uint32) bool {
return b.isNull(b, d)
} |
ok, I just want to leave this issue here, with a playground link that shows the first answer I proposed above is correct. https://play.golang.org/p/FMvisWS9tuP package main
import "fmt"
type nullTester func(*Bast, uint32) bool
type Bast struct {
isNull nullTester
}
func isNull(b *Bast, d uint32) bool {
return d == 0
}
func NewBast() (b Bast) {
b.isNull = isNull
return
}
// IsNull - tests if a value in the tree is null
func (b *Bast) IsNull(d uint32) bool {
return b.isNull(b, d)
}
func main() {
b := NewBast()
fmt.Println("is 0 == 0 ?", b.IsNull(0))
fmt.Println("is 1 == 0 ?", b.IsNull(1))
} I don't know if my solution is idiomatic, and I simply have not been able to understand how to bind different functions in. The question of how to bind a slice in is not the bit that is challenging, as it can be defined as It's the fact that I have found a way to implement function overloading that makes me think this is not idiomatic but I see no way in which this violates type safety at all. If the syntax for type func allowed the specification of a method binding, the resultant code would be a lot cleaner and lack this boilerplate wrapper that allows the passing of the bound type through the interface method, but if I may submit this as a proposal for a grammar extension I think this would in no way break Go 1.0 code, that I know of (of course I could be wrong, but extensions usually don't break things), but without this change this above is how to do function overloading in Go, at least one way anyway. I simply could not figure out or follow any of the methods I have seen that would work outside of a single file scope, and I don't think combining multiple different interface/class specs in one source file is either maintainable or flexible for implementing especially data types that need to work with arbitrary but analogous different data payloads. |
@l0k1verloren I'm unclear from reading the above whether you think there is a problem here, or whether this is more of a discussion. I can't see an issue with the code you just posted; it functions as expected. Please can I ask you to continue the discussion outside the issue tracking system? The Go project does not use its bug tracker for general discussion or asking questions. The Github bug tracker is only used for tracking bugs and proposals going through the Proposal Process. The questions wiki page has a good list of places for everything else. Thanks |
Simply that because I can't add a method binding to a The type syntax lacks the binding part that causes otherwise identical function signature to be 'not found'. There is no reason I can think of except OOP-phobia, and as you can see by my code, it works, it's not violating any type safety, and it's a useful construction for being able to generalise small parts of libraries to deal with a variety of types (it came up for me because I was working on a binary search tree, a clear case for the need of polymorphism to not require so much boilerplate). It's a side thing but I also think the special exception for slices that do not behave consistently compared to every other Go type. I had to encapsulate a slice inside a struct in order to allow embedding into one library the ability to change a back-store. This is just a limited case, and very inconsistent, and very much in line with the subject of this issue as well. It does not in fact stop polymorphism, it just makes it cumbersome to implement, for absolutely no reason. And regarding your last comment, it IS a bug that on one hand every other case is covered except for method (struct/variable type) binding. On both points. You can see that my code works, it does not present any risk of bugs arising that I most vigorously support Go for keeping as goals. The workarounds were not difficult, but at the same time, changes in the language spec don't even go into the 2.0 discussion at all. They would break no code, neither integrating slices with interface{}, nor the addition of (in a reasonable, unambiguous place) variable binding to |
I have asked in a couple of other places but it occurred to me this might be a good place to ask, as maybe this is a 'bug' of some sort.
When defining a function type, viz:
the compiler flags a type mismatch if trying to assign a function that has otherwise identical signature except is prefixed with a binding to an interface. I could not find any information about specifying the binding type in this type of declaration. As such I worked out that it would be possible to implement a binding for a first class function by placing the primary code within one function, with the pointer to the type in the parameter list, and then calling this function, pretty much pass-through, as a wrapper, and then the function can be called as a child of the parent typed variable without having to explicitly pass the pointer to the struct or variable we want to bind to.
I am curious to know if there is some reason why this isn't in the syntax, or if simply I have gone a long way around to enable me to substitute a set of functions to operate on similar but comparable other types within a bigger library, with my hackish solution.
This is not a perfect example, as in fact in my code I also have a slice embedded into an
interface{}
variable in the struct, but this shows all the elements I am referring to and as to how I worked around this seeming limitation (I may just have not fully understood how composition and embedding work):As you can see, if I have assigned this function to a variable in the struct, and the type bound function will be in the same scope, I should thus be able to override a function through the use of first class functions in this way. It doesn't really break any typing rules, it's just that the declaration at the top does not match the function at the bottom and thus I can't put
b.isNull = IsNull
as the compiler says it can't find the name.The text was updated successfully, but these errors were encountered: