> For the complete documentation index, see [llms.txt](https://denglj.gitbook.io/essential-go/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://denglj.gitbook.io/essential-go/common-standard-libraries/39-reflection/primitive-types.md).

# 原始类型

让我们来看看可以对int或string这种原始类型做什么操作。

## 获取类型

```go
package main

import (
	"fmt"
	"reflect"
)

func printType(v interface{}) {
	rv := reflect.ValueOf(v)
	typ := rv.Type()
	typeName := ""
	switch rv.Kind() {
	case reflect.Ptr:
		typeName = "pointer"
	case reflect.Int:
		typeName = "int"
	case reflect.Int32:
		typeName = "int32"
	case reflect.String:
		typeName = "string"
	// ... handle more cases
	default:
		typeName = "unrecognized type"
	}
	fmt.Printf("v is of type '%s'. Size: %d bytes\n", typeName, typ.Size())
}

func main() {
	printType(int32(3))
	printType("")
	i := 3
	printType(&i) // *int i.e. pointer to int
}

/*
---------OUTPUT---------
v is of type 'int32'. Size: 4 bytes
v is of type 'string'. Size: 16 bytes
v is of type 'pointer'. Size: 8 bytes
*/
```

在实际代码中，你可以处理你关心的[所有类型](/essential-go/common-standard-libraries/39-reflection/reflect-kind.md)。

## 获取值

```go
package main

import (
	"fmt"
	"reflect"
)

func getIntValue(v interface{}) {
	var reflectValue = reflect.ValueOf(v)
	n := reflectValue.Int()
	fmt.Printf("Int value is: %d\n", n)
}

func main() {
	getIntValue(3)
	getIntValue(int8(4))
	getIntValue("")
}

/*
Int value is: 3
Int value is: 4
panic: reflect: call of reflect.Value.Int on string Value

goroutine 1 [running]:
reflect.Value.Int(0x111f900, 0x1162920, 0x98, 0x0)
        /usr/local/go/src/reflect/value.go:986 +0x1a9
main.getIntValue(0x111f900, 0x1162920)
        /Users/ju/gowork/src/test/main.go:24 +0x7e
main.main()
        /Users/ju/gowork/src/test/main.go:31 +0x7b
Exiting.
*/
```

为了最小化API的表示，`Int()`返回`int64`可处理所有有符号整型值(`int8`, `int16`, `int32`, `int64`)。

`UInt()`方法返回`uint64`，可处理每种有符号整型值(`uint8`, `uint16`, `uint32`, `uint64`)。

试图从不兼容类型的值(如字符串)获取整型值，将会引发恐慌。

为了避免恐慌，您可以先用`Kind()`方法检查值的类型。

获取值的所有方法：

* `Bool() bool`
* `Int() int64`
* `UInt() uint64`
* `Float() float64`
* `String() string`
* `Bytes() []byte`

## 设置值

```go
package main

import (
	"fmt"
	"reflect"
)

type S struct {
	N int
}

func setIntPtr() {
	var n int = 2
	reflect.ValueOf(&n).Elem().SetInt(4)
	fmt.Printf("setIntPtr: n=%d\n", n)
}

func setStructFieldDirect() {
	var s S
	reflect.ValueOf(&s.N).Elem().SetInt(5)
	fmt.Printf("setStructFieldDirect: n=%d\n", s.N)
}

func setStructPtrField() {
	var s S
	reflect.ValueOf(&s).Elem().Field(0).SetInt(6)
	fmt.Printf("setStructPtrField: s.N: %d\n", s.N)
}

func handlePanic(funcName string) {
	if msg := recover(); msg != nil {
		fmt.Printf("%s panicked with '%s'\n", funcName, msg)
	}
}

func setStructField() {
	defer handlePanic("setStructField")
	var s S
	reflect.ValueOf(s).Elem().Field(0).SetInt(4)
	fmt.Printf("s.N: %d\n", s.N)
}

func setInt() {
	defer handlePanic("setInt")
	var n int = 2
	rv := reflect.ValueOf(n)
	rv.Elem().SetInt(4)
}

func setIntPtrWithString() {
	defer handlePanic("setIntPtrWithString")
	var n int = 2
	reflect.ValueOf(&n).Elem().SetString("8")
}

func main() {
	setIntPtr()
	setStructFieldDirect()
	setStructPtrField()

	setInt()
	setStructField()

	setIntPtrWithString()
}

/*
---------OUTPUT-----------
setIntPtr: n=4
setStructFieldDirect: n=5
setStructPtrField: s.N: 6
setInt panicked with 'reflect: call of reflect.Value.Elem on int Value'
setStructField panicked with 'reflect: call of reflect.Value.Elem on struct Value'
setIntPtrWithString panicked with 'reflect: call of reflect.Value.SetString on int Value'
*/
```

像`setInt`和`setStructField`展示的那样，只有拿到指向值的指针时，才可以修改值。

因为`reflect.ValueOf()`创建了一个`reflect.Value` 变量，它是一个指向值的指针变量，所以你需要用`Elem()`来获取`reflect.Value`所表示的值本身，然后再调用`SetInt()` 为它设置值。

`setStructPtrField`展示了如何通过字段在结构体中的位置来取得字段值的引用。

试图设置类型不兼容的值会导致恐慌。

设置值的方法跟读取值的方法是镜像存在的：

* `SetBool(v bool)`
* `SetInt(v int64)`
* `SetUInt(v uint64)`
* `SetFloat(v float64)`
* `SetString(v string)`
* `SetBytes(v []byte)`


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://denglj.gitbook.io/essential-go/common-standard-libraries/39-reflection/primitive-types.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
