uhm, there is a bit of a mix-up with the yes-vs-no thing and negating. I'm apparently a bit tired, disregard the actual "no" and focus on the rest of the reply, explaining why what you want can't be done :)
On Sat, Jan 13, 2018 at 1:35 AM, Axel Wagner <axel.wagner...@googlemail.com> wrote: > > > On Fri, Jan 12, 2018 at 11:23 PM, Peter Mogensen <a...@one.com> wrote: > >> >> >> On 2018-01-12 22:22, Axel Wagner wrote: >> > Yes, you can *test* if the dynamic value has a specific type (and >> > extract it if so). That is not the same as operating on the dynamic >> > value (e.g. by dereferencing it) *without* knowing its type. >> >> I know I can test the type. But the issue was specifically to >> dereference the first pointer while keeping the actual object. >> >> > Go does not have parametrically polymorphic types - and even if it had, >> > there wouldn't be any sensible type you could assume here, given that >> > it's only known at runtime. There simply is no type that the extracted >> > value could have. Like, what would the type of t be in your example, in >> > the **<Something> case? >> >> It seems we are constantly talking pass each other. There was two >> questions here >> 1) Can it be done in Go as the Go spec is now? >> 2) Is it in general an ambigious task? >> >> So let's assume we already have answered 1) with "no". (I guess) >> It seems you are trying to argue that the answer to 2) is "YES", but >> doing it with reference to current Go spec. >> > > But the answer to 2 is "no, not in a type-safe way". It necessarily > requires reflection. Even if we'd assume we somehow magically know that the > dynamical value of the interface is some pointer type. That doesn't > actually help us, in any reasonable way. We can dereference it, but we > wouldn't know what the thing it's pointing to is. Or to put it another way: > To dereference a pointer, you'd have to know - at the very least - the size > of the thing it's pointing to. And to do it in a type-safe way, you'd have > to know the *type* of the thing it's pointing to. > > Yes, in theory, the compiler an inspect the type-info of the interface, > see that it's a pointer-type and then construct a new interface-value, with > dynamic type "type of the pointee" and dynamic value "pointee" - that's > reflection. I.e. the compiler would emit code for the equivalent of > v := reflect.ValueOf(v).Elem().Interface() > That is the best you can do, but in particular, you don't have any static > information about what the value is you are operating on, so you can't call > any methods on it, you can't dereference it, you can't do… anything with > it, really. Like, you can't actually do any better than what reflection > gives you - and reflection already works. > > That's why I say that, if you know the type, use that knowledge to get > static assertions on it. If you don't use reflection. And that is > fundamentally all you can do in a statically typed language. > > Your request is essentially equivalent to reflection as a > language-feature, which is essentially equivalent to making Go a > dynamically typed language. > > I'm perfectly aware that in a case in a type switch like this >> >> switch t := i.(type) { >> } >> >> ... t needs to have a type in each case clause, and the only type it can >> have in lack of a specific type mentioned, is interface{} >> >> But still ... that's an argument for 1) - not for 2) >> >> > Yes, it is in general ambiguous what is meant. >> >> No, I don't think so. >> >> There nothing ambigious about generic operation of turning **T into *T. >> The only reason it cannot be done here is because the deference operator >> needs to operate on a concrete type and we have an interface{}. >> >> It might not be meaningful to define an actual generic function >> mechanism for this, since for the compiler to check the types there is >> not much more than the dereferencing which can be done >> But it is possible to state this in C++: >> >> template<class T> >> T *f(T **p) { >> return *p; >> } >> > > This is not the same. In the case of this C++ code, the actual type of T > is statically known. In your Go case of getting passed an interface{}, you > have no static information about the type (or rather: You have the > information that it's an interface{} value). This is what I meant when I > said, parametric polymorphism alone wouldn't even help you a priori; unless > it's instantiated at runtime (say, like in Python). > > I don't know enough C++ to talk about this competently, but a quick > googling suggests the rough equivalent to Go's interfaces in C++ (in terms > of implementation) are polymorphic objects: Objects that keep dynamic type > info around. And I assume, if you'd actually try to do it using that, you'd > run into similar problems and would end up having to use typeid() - which > is the equivalent to reflection. But yes, as I said, I can't talk > competently about C++. > -- 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+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.