How do I unwrap a wrapped struct in golang? [duplicate] - go

This question already has answers here:
struct type embedded fields access
(3 answers)
accessing struct fields from embedded struct
(2 answers)
Nameless fields in Go structs?
(2 answers)
If struct A is embedded in B, can methods on A access method and fields of B?
(2 answers)
Closed 1 year ago.
So I have been searching and can't seem to find how to get the backend struct for a wrapped struct in go.
This is the use case: I am using traffic to manage my web app and it uses it's own wrapped version of the http.Request as well as several others. the declaration looks like this:
type Request struct {
*http.Request
}
I am trying to incorporate go-guardian and I need to send an http.Request to this function:
Authenticate(r *http.Request) (Info, error)
The question is how do I get the *http.Request that the traffic.Request was made out of?
I seem to remember seeing a way to do this in a tutorial somewhere but I haven't been able to find it (the problem is I'm not sure I'm using the right term for a wrapped struct).
Any feedback would be graetly appreciated - thank you.

An embedded field can be accessed using its type name:
type Request struct {
*http.Request
}
For the above:
func f(r *Request) {
// This will pass the embedded *http.Request
g(r.Request)
}

Related

Go Generics - Hold a map of generic interfaces [duplicate]

This question already has answers here:
Why a generic can't be assigned to another even if their type arguments can?
(1 answer)
Can I construct a slice of a generic type with different type parameters?
(2 answers)
Go generic container with different runtime types
(1 answer)
Closed 11 months ago.
I'm refactoring some of my code now that Go 1.18 is out with the new Generics feature.
I've created a generic interface i.e
type IExample[T any] interface{
ExampleFunc(ex T) T
}
Somewhere in my code, I want to store several implementations of this interface in a map and use them generically in my code.
mapping := map[string]IExample{
// .......
}
But the go compiler throws this error cannot use generic type types.SettingsAdapter[T any] without instantiation
So, I tried adding any to the generic type
mapping := map[string]IExample[any]{
// .......
}
Which resulted in the following error
IExample[any] does not implement IExampleImpl[ExampleT]
At this point, I feel that there's something I'm missing while implementing the code, or that I'm just using this feature in a way that it wasn't meant to be used.
Thanks :)

Inheritance syntax. What is the difference?

In Go what is the difference below?
I tried to search, but I couldn't think of a right term to describe them. How are they officially called?
#1 - Parent inside struct:
type MyTime struct {
time.Time
}
#2 - Parent right after my type without struct definition:
type MyTime time.Time
For #2, I can initialize my type with another time.Time like mt := MyTime(t).
How to initialize #1 type with another time.Time variable?
Go is not an object oriented language, there is no type hierarchy and inheritance. For details, see What is the idiomatic way in Go to create a complex hierarchy of structs? and Go embedded struct call child method instead parent method.
Your first example creates a new type MyTime embedding time.Time. By embedding a type, all fields and methods of the embedded type gets promoted and are available as if they were fields or methods of the embedder type, very handy when you want to implement an interface for example (because the promoted methods will "exist" without having to declare them).
You can instantiate it like (for details, see Golang embedded struct type):
t := MyTime{Time: time.Now()}
Your second example creates a new type, all methods will be stripped from it. This comes handy when you do not want the existing methods to be part of the new type. A shining example of this is to define the String() method or override marshaling behavior when you want to call the original behavior in your implementation, for details see Call json.Unmarshal inside UnmarshalJSON function without causing stack overflow. You can create a value of it using a simple type conversion:
t := MyTime(time.Now())

Calling an exported method on a unexported field

I know, similar questions have been asked, but I found no answer for that case:
type ExportedStruct struct{ //comes from a dependency, so I can't change it
unexportedResource ExportedType
}
I want to call an exported method Close() on unexportedResource.
What I did was:
rs := reflect.ValueOf(myExportedStructPtr).Elem() //myExportedStructPtr is a pointer to an ExportedStruct object
resourceField := rs.FieldByName("unexportedResource")
closeMethod := resourceField.MethodByName("Close")
closeMethod.Call([]reflect.Value{reflect.ValueOf(context.Background())})
, which results in reflect.flag.mustBeExported using value obtained using unexported field.
This is quite annoying since I want to run more than one test which utilizes ExportedStruct, but I can't as long as the underlying resource is not used.
Since I can access private fields (as explained here) I have a bit hope that I'm allowed to access the public method of that field somehow, too. Maybe I'm just reflecting wrong?
Unexported fields are for the declaring package only. Stop messing with them. They are not for you.
The linked answer can only access it by using package unsafe, which is not for everyday use. Package unsafe should come with a "not to touch" manual.
If you do need to access unexportedResource, make it exported. Either the field, or add a method to the type that calls unexportedResource.Close(). Or add a utility function to the package that does this (functions in the same package can access unexported fields and identifiers).
While #icza's answer gives you reason why you should not do it, here is a way of how to do it using reflect and unsafe:
var t pkg.T
v := reflect.ValueOf(&t).Elem()
f := v.FieldByName("t")
rf := reflect.NewAt(f.Type(), unsafe.Pointer(f.UnsafeAddr())).Elem()
rf.MethodByName("Print").Call(nil)
playground: https://play.golang.org/p/CmG9e4Bl9gg
I am afraid that what you are trying to do is impossible through reflection.
Below is the implementation of reflect.Call:
func (v Value) Call(in []Value) []Value {
v.mustBe(Func)
v.mustBeExported()
return v.call("Call", in)
}
As you can see there is an explicit check (i.e. mustBeExported()) if Value was obtained from an exported field or not.
Typically there is a reason why fields are not exported. If you want to manipulate that field you will have to use methods implemented by the ExportedStruct struct.
If you can modify the code where ExportedStruct is defined, you can easily implement a wrapper Close method on that. For example:
type ExportedStruct struct{
unexportedResource ExportedType
}
func (e ExportedStruct) Close(){
e.unexportedResource.Close()
}

How do I properly use these variables in a separate function in Go?

Apologies for what is likely a very elementary question.
I'm using http's listenAndServe, and it calls the following function:
func library(writer http.ResponseWriter, request *http.Request)
A lot of the code contained in that function applies elsewhere, so I wanted to bring it out into another function, such as:
func commonFunction(doThing bool, writer http.ResponseWriter, request *http.Request)
But is that function header for commonFunction correct if I'm passing those two variables from library into it?
Would I call it as commonFunction(true, writer, request)?
I'm mostly confused if I should be passing pointers to these variables? It would make sense not to for http.Request as it's already a pointer, but what about http.ResponseWriter, surely I don't want to recreate the variable?
Your signature looks fine. One part many people overlook when they first start doing web work in Go is that the writer http.ResponseWriter is an interface value. In Go interface values are reference types meaning that the writer variable you're being passed already internally contains a pointer to the concrete value that's satisfying that interface. You can feel free to pass your writer on to commonFunction and it's already a reference.

How does type aliases work in Go? [duplicate]

This question already has an answer here:
Calling method of named type
(1 answer)
Closed 7 years ago.
I have a type wrapper in my code:
package my_package
import "github.com/gin-gonic/gin"
type Server *gin.Engine
It works perfectly fine to use it within my package like:
func NewServer() Server {
s:= Server(gin.Default())
// I can call *gin.Engine functions on my s here without problems
return s
}
In my test suite (which resides in another package) I import my package and get the Server type. However, when I try to call some "inherited" functions on it doesn't work.
server_test.go:68: server.ServeHTTP undefined (type my_package.Server has no field or method ServeHTTP)
What's going on?
EDIT
The solution I found is related to #jiang-yd answer below:
Change the type to a embedding struct
type Server struct {
*gin.Engine
}
and change the "cast"
s := Server{gin.Default()}
in official document, there are two kinds of type, static type and underlying type. Server is your static type and *gin.Engine is the underlying type. most place in golang just use static type, so Server and *.gin.Engine are two types. check the golang spec
well it not help you in your problem. in your situation, you need embedding struct of golang, which help you inherit all method from one struct to another.

Resources