Thursday 11 April 2019

go - Golang type aliasing (type SampleType otherType !== otherType)?



I am building a simple router for which the code is below.



I have a callback that takes type Res as a parameter. Initially I was under the impression that type Res http.ResponseWriter would simply mean that Res is an alias for http.ResponseWriter, as passing http.ResponseWriter into the callback with a Res param worked fine.




I later decided I wanted to wrap my own functionality around the response provided to the callback, and so changed the type Res http.ResponseWriter to type Res response.Response - response being my own package (please look at what is commented out in the source below). After doing so I get "Cannot use newResponse (type response.Response) as type Res in argument to urlCallback"



I looked at the http.ResponseWriter source code and noticed it is an interface whereas my response.Response is a struct, is this where the problem lies?



Does setting a type as another type does not necessarily alias it? And if not, then why did passing in http.ResponseWriter for type Res work initially?



package Router

import (
"fmt"

"net/http"
"net/url"
"log"
// "./response"
)

// type Res response.Response
type Res http.ResponseWriter
type Req *http.Request


type RouteMap map[string]func(Res, Req)
type MethodMap map[string]RouteMap

type Router struct {
Methods MethodMap
}

func (router *Router) Get(urlString string, callback func(Res, Req)) {
parsedUrl, err := url.Parse(urlString)


if(err != nil) {
panic(err)
}

router.Methods["GET"][parsedUrl.Path] = callback
}

func (router *Router) initMaps() {
router.Methods = MethodMap{}
router.Methods["GET"] = RouteMap{}

}

func (router Router) determineHandler(w http.ResponseWriter, r *http.Request) {
methodMap := router.Methods[r.Method]
urlCallback := methodMap[r.URL.Path]

// newResponse := response.NewResponse(w)

if(urlCallback != nil) {
// urlCallback(newResponse, r)

urlCallback(w, r)
}
}

func (router Router) Serve(host string, port string) {
fullHost := host + ":" + port

fmt.Println("Router is now serving to:" + fullHost)
http.HandleFunc("/", router.determineHandler)


err := http.ListenAndServe(fullHost, nil)

if err == nil {
fmt.Println("Router is now serving to:" + fullHost)
} else {
fmt.Println("An error occurred")

log.Fatal(err)
}
}



The commented out code describes the issue im having/what im trying to do


Answer



Doing



type Res response.Response


you define new type, which is not interchangeable with original




to convert you should do



newResponse := Res(response.NewResponse(w))


when you do



type Res http.ResponseWriter



your type Res is an interface and http.ResponseWriter implement it, so can be used as arg in func where Res wanted


No comments:

Post a Comment

php - file_get_contents shows unexpected output while reading a file

I want to output an inline jpg image as a base64 encoded string, however when I do this : $contents = file_get_contents($filename); print &q...