Golang TypeOf没有实例并将结果传递给func [英] Golang TypeOf without an instance and passing result to a func
问题描述
是否有可能在没有实例的情况下获取Type?我见过一些利用 reflect.TypeOf()
的例子,但它们都处理一个实例。
以下是我尝试做的一个片段:
import(
net / http
)
类型ParamReader struct {
//从中提取参数的请求
context * http。请求
}
//用特定的http请求初始化ParamReader。这用作
//作为我们param阅读器的上下文。所有后续调用将验证
//在此分配的http.Request
中存在的参数func(p * ParamReader)上下文(r * http.Request){
p.context = r
}
//验证给定参数's'是否存在以及类型为't'的有效
//值。如果从
//其字符串表示形式到't'的转换是可能的,则该值有效demaed
func(p * ParamReader)要求(s字符串,t类型){
// if上下文没有'
// addError('s'不存在)
//返回
if(t == typeof(uint64)) {
//如果不是s - > uint64
// addError('s'不是有效的uint64)
} else if(t == typeof(uint32)){
// ....
} / ....
}
我的例子是
func(h * Handler)OnRequest(r * http.Request){
h.ParamReader.Context(r)
h.ParamReader.Require(age,uint16)
h.ParamReader.Require(name,string)
h.ParamReader.Require(coolfactor,uint64)
h .ParamReader.Optional(email,string,unspecified)
h.ParamReader.Optional(money,uint64,0)
如果h.ParamReader.HasErrors( ){
//迭代或者对错误做些什么
} else {
coolness:= h.ParamReader.ReadUint64(coolfactor)
email:= h.ParamReader。 ReadString(email)
money:= h.ParamReader.ReadUint64(0)
}
}
请注意,写完后我意识到我可以提供一个RequireUint64
,R equireUint32
等等,也许这就是Go的方式吗?
是的,这是可能的。诀窍是从一个指向类型的指针开始(它的值可以是一个类型 nil
,这非常好),然后使用 Type.Elem()
来获取指向类型的 reflect.Type
描述符( base
$ t:=反映.TypeOf((* int)(nil)).elem()
fmt.Println(t)
$ b $ = reflect.TypeOf((* http.Request)(nil))。Elem ()
fmt.Println(t)
$ b $ = reflect.TypeOf((* os.File)(nil))。Elem()
fmt.Println(t)
输出(在 Go Playground ):
int
http .Request
os.File
请参阅相关问题:
如果要传递类型并在<$ c $中使用它们c> switch es,您可以像这样创建并将它们存储在全局变量中,并引用全局变量:
var(
intType = reflect.TypeOf((* int)(nil))
httpRequestType = reflect.TypeOf((* http.Request)(nil))
osFileType = reflect.TypeOf((* os.File)(nil))
int64Type = reflect.TypeOf((* uint64)(nil))
)
func printType (类型:int)
大小写httpRequestType:
fmt.Println(t reflect.Type){
switch t {
case intType:
fmt.Println类型:http.request)
case osFileType:
fmt.Println(Type:os.file)
case int64Type:
fmt.Println(Type:uint64 )
默认:
fmt.Println(Type:Other)
}
}
func main(){
printType(intType)
printType(httpRequestType)
printType(osFileType)
printType(int64Type)
}
上面的输出(在 Go Playground 上试用): p>
类型:int
类型:http.request
类型:os.file
类型:uint64
但是说实话,如果你像这样使用它,而你没有使用 reflect.Type
的方法,然后创建常量要容易得多并且效率更高。它可能看起来像这样:
$ p $ type TypeDesc int
$ b $ const(
typeInt TypeDesc = iota
typeHttpRequest
typeOsFile
typeInt64
)
func printType(t TypeDesc){
switch t {
case typeInt:
fmt.Println(Type:int)
case typeHttpRequest:
fmt.Println(Type:http.request)
案例类型OsFile:
fmt。 println(Type:os.file)
case typeInt64:
fmt.Println(Type:uint64)
default:
fmt.Println(Type:Other )
$ b $ func main(){
printType(typeInt)
printType(typeHttpRequest)
printType(typeOsFile)
printType(typeInt64)
}
输出是一样的。试试去游乐场。
Is it possible in go to get a "Type" without an instance? I've seen some examples that utilize reflect.TypeOf()
but they all deal with an instance.
Below is a snippet of what I am attempting to do:
import (
"net/http"
)
type ParamReader struct {
// The request from which to extract parameters
context *http.Request
}
// Initialize the ParamReader with a specific http request. This serves
// as the 'context' of our param reader. All subsequent calls will validate
// the params that are present on this assigned http.Request
func (p *ParamReader) Context(r *http.Request) {
p.context = r
}
// Validate that a given param 's' is both present and a valid
// value of type 't'. A value is demeed valid if a conversion from
// its string representation to 't' is possible
func(p *ParamReader) Require(s string, t Type) {
// if context not have 's'
// addError('s' is not present)
// return
if( t == typeof(uint64)) {
// If not s -> uint64
// addError('s' is not a valid uint64)
} else if (t == typeof(uint32)) {
// ....
} / ....
}
An example of my usage would be
func (h *Handler) OnRequest(r *http.Request) {
h.ParamReader.Context(r)
h.ParamReader.Require("age", uint16)
h.ParamReader.Require("name", string)
h.ParamReader.Require("coolfactor", uint64)
h.ParamReader.Optional("email", string, "unspecified")
h.ParamReader.Optional("money", uint64, "0")
if h.ParamReader.HasErrors() {
// Iterate or do something about the errors
} else {
coolness := h.ParamReader.ReadUint64("coolfactor")
email := h.ParamReader.ReadString("email")
money := h.ParamReader.ReadUint64(0)
}
}
Note, after writing this out, I realize I could provide a "RequireUint64"
, "RequireUint32"
, etc.. perhaps that would be the Go way?
Yes, it's possible. The trick is to start from a pointer to the type (whose value can be a typed nil
, that's perfectly OK), and then use Type.Elem()
to get the reflect.Type
descriptor of the pointed type (the base type).
See some examples:
t := reflect.TypeOf((*int)(nil)).Elem()
fmt.Println(t)
t = reflect.TypeOf((*http.Request)(nil)).Elem()
fmt.Println(t)
t = reflect.TypeOf((*os.File)(nil)).Elem()
fmt.Println(t)
Output (try it on the Go Playground):
int
http.Request
os.File
See related questions:
Golang reflect: Get Type representation from name?
How to get the string representation of a type?
If you want to pass around the types and use them in switch
es, you can create and store them in global variables once like this, and refer to the global vars:
var (
intType = reflect.TypeOf((*int)(nil))
httpRequestType = reflect.TypeOf((*http.Request)(nil))
osFileType = reflect.TypeOf((*os.File)(nil))
int64Type = reflect.TypeOf((*uint64)(nil))
)
func printType(t reflect.Type) {
switch t {
case intType:
fmt.Println("Type: int")
case httpRequestType:
fmt.Println("Type: http.request")
case osFileType:
fmt.Println("Type: os.file")
case int64Type:
fmt.Println("Type: uint64")
default:
fmt.Println("Type: Other")
}
}
func main() {
printType(intType)
printType(httpRequestType)
printType(osFileType)
printType(int64Type)
}
Output of the above (try it on the Go Playground):
Type: int
Type: http.request
Type: os.file
Type: uint64
But honestly, if you're using it like this way and you're not using reflect.Type
's methods, then creating constants is much easier and more efficient. It could look like this:
type TypeDesc int
const (
typeInt TypeDesc = iota
typeHttpRequest
typeOsFile
typeInt64
)
func printType(t TypeDesc) {
switch t {
case typeInt:
fmt.Println("Type: int")
case typeHttpRequest:
fmt.Println("Type: http.request")
case typeOsFile:
fmt.Println("Type: os.file")
case typeInt64:
fmt.Println("Type: uint64")
default:
fmt.Println("Type: Other")
}
}
func main() {
printType(typeInt)
printType(typeHttpRequest)
printType(typeOsFile)
printType(typeInt64)
}
Output is the same. Try it on the Go Playground.
这篇关于Golang TypeOf没有实例并将结果传递给func的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!