Golang类型别名(type SampleType otherType!== otherType)是什么意思?

huangapple go评论82阅读模式
英文:

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

问题

我正在构建一个简单的路由器,下面是代码。

我有一个回调函数,它以类型 Res 作为参数。最初我以为 type Res http.ResponseWriter 只是意味着 Res 是 http.ResponseWriter 的别名,因为将 http.ResponseWriter 传递给带有 Res 参数的回调函数是可以正常工作的。

后来我决定在回调函数中包装自己的功能,所以将 type Res http.ResponseWriter 改为 type Res response.Response - response 是我自己的包(请查看下面源代码中的注释部分)。这样做后,我得到了 "Cannot use newResponse (type response.Response) as type Res in argument to urlCallback" 的错误。

我查看了 http.ResponseWriter 的源代码,注意到它是一个接口,而我的 response.Response 是一个结构体,这是问题所在吗?

将一个类型设置为另一个类型并不一定是别名吗?如果不是,那么为什么最初将 http.ResponseWriter 传递给类型为 Res 的参数是可以工作的?

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)
	}
}

注释掉的代码描述了我遇到的问题/我想要做的事情。

英文:

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

答案1

得分: 2

你正在定义一个新类型Res,它与原始类型不可互换。

要进行转换,你可以这样做:

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

当你这样做时:

type Res http.ResponseWriter

你的类型Res是一个接口,而http.ResponseWriter实现了它,因此可以作为参数在需要Res的函数中使用。

英文:

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

huangapple
  • 本文由 发表于 2015年1月11日 21:36:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/27887706.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定