- 将原有main.go中的多个函数移至新文件re1.go - 保留main.go中的主函数调用结构 - 添加Payment结构体定义到types.go - 清理main.go中不再使用的导入和类型定义- 确保所有功能逻辑保持不变并可正常运行
362 lines
9.2 KiB
Go
362 lines
9.2 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
"strings"
|
|
)
|
|
|
|
func printDetails(values ...Product) {
|
|
for _, elem := range values {
|
|
Printfln("Name: %v, Category: %v, Price: %v", elem.Name, elem.Category, elem.Price)
|
|
}
|
|
}
|
|
func printDetails1(values ...interface{}) {
|
|
Printfln("\nprintDetails1:")
|
|
for _, elem := range values {
|
|
switch val := elem.(type) {
|
|
case Product:
|
|
Printfln("Name: %v, Category: %v, Price: %v", val.Name, val.Category, val.Price)
|
|
case Customer:
|
|
Printfln("Name: %v, City: %v", val.Name, val.City)
|
|
}
|
|
}
|
|
}
|
|
|
|
func printDetails2(values ...interface{}) {
|
|
Printfln("\nprintDetails2:")
|
|
for _, elem := range values {
|
|
fieldDetails := []string{}
|
|
elemType := reflect.TypeOf(elem)
|
|
elemValue := reflect.ValueOf(elem)
|
|
if elemType.Kind() == reflect.Struct {
|
|
for i := 0; i < elemType.NumField(); i++ {
|
|
field := elemType.Field(i)
|
|
fieldVal := elemValue.Field(i)
|
|
fieldDetails = append(fieldDetails, fmt.Sprintf("%v: %v", field.Name, fieldVal))
|
|
}
|
|
Printfln("%v: %v", elemType.Name(), strings.Join(fieldDetails, ", "))
|
|
} else {
|
|
Printfln("%v: %v", elemType.Name(), elemValue)
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
func printDetails3(values ...interface{}) {
|
|
Printfln("\nprintDetails3:")
|
|
for _, elem := range values {
|
|
elemType := reflect.TypeOf(elem)
|
|
Printfln("Name: %v ,PkgPath: %v , Kind: %v", elemType.Name(), getTypePath3(elemType), elemType.Kind())
|
|
}
|
|
}
|
|
|
|
func getTypePath3(elemType reflect.Type) interface{} {
|
|
path := elemType.PkgPath()
|
|
if path == "" {
|
|
return "(built-in)"
|
|
}
|
|
return path
|
|
}
|
|
|
|
func printType(elemValue *reflect.Value) {
|
|
switch elemValue.Kind() {
|
|
case reflect.Bool:
|
|
Printfln("Bool: %v", elemValue.Bool())
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
Printfln("Int: %v", elemValue.Int())
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
Printfln("Uint: %v", elemValue.Uint())
|
|
case reflect.Float32, reflect.Float64:
|
|
Printfln("Float: %v", elemValue.Float())
|
|
case reflect.String:
|
|
Printfln("String: %v", elemValue.String())
|
|
case reflect.Ptr:
|
|
var val = elemValue.Elem()
|
|
if val.Kind() == reflect.Int {
|
|
Printfln("Pointer to Int: %v", val.Int())
|
|
}
|
|
case reflect.Struct:
|
|
Printfln("Struct type: %v string: %v", elemValue.Type(), elemValue.String())
|
|
default:
|
|
Printfln("Unsupported type: %v string: %v", elemValue.Type(), elemValue.String())
|
|
|
|
}
|
|
}
|
|
|
|
func printDetails4(values ...interface{}) {
|
|
Printfln("\nprintDetails4:")
|
|
for _, elem := range values {
|
|
elemValue := reflect.ValueOf(elem)
|
|
printType(&elemValue)
|
|
}
|
|
}
|
|
|
|
var intPtrType = reflect.TypeOf((*int)(nil))
|
|
var byteSliceType = reflect.TypeOf([]byte(nil))
|
|
|
|
func printDetails5(values ...interface{}) {
|
|
Printfln("\nprintDetails5:")
|
|
for _, elem := range values {
|
|
elemValue := reflect.ValueOf(elem)
|
|
elemType := reflect.TypeOf(elem)
|
|
if elemType == intPtrType {
|
|
Printfln("Type Pointer to Int: %v", elemValue.Elem().Int())
|
|
continue
|
|
} else if elemType == byteSliceType {
|
|
Printfln("Type Byte slice: %v", elemValue.Bytes())
|
|
continue
|
|
}
|
|
|
|
printType(&elemValue)
|
|
}
|
|
}
|
|
|
|
func selectValue6(data interface{}, index int) (result interface{}) {
|
|
Printfln("\nselectValue6:")
|
|
dataVal := reflect.ValueOf(data)
|
|
if dataVal.Kind() == reflect.Array || dataVal.Kind() == reflect.Slice {
|
|
result = dataVal.Index(index).Interface()
|
|
}
|
|
return
|
|
}
|
|
|
|
func incrementOrUpper7(values ...interface{}) {
|
|
Printfln("\nincrementOrUpper7:")
|
|
for _, elem := range values {
|
|
elemValue := reflect.ValueOf(elem)
|
|
if elemValue.Kind() == reflect.Ptr {
|
|
elemValue = elemValue.Elem()
|
|
}
|
|
if elemValue.CanSet() {
|
|
switch elemValue.Kind() {
|
|
case reflect.String:
|
|
elemValue.SetString(strings.ToUpper(elemValue.String()))
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
elemValue.SetInt(elemValue.Int() + 1)
|
|
default:
|
|
Printfln("unhandled default case")
|
|
}
|
|
Printfln("Modified Value: %v", elemValue)
|
|
} else {
|
|
Printfln("Cannot set %v: %v", elemValue.Kind(), elemValue)
|
|
}
|
|
}
|
|
}
|
|
|
|
func setAll9(src interface{}, targets ...interface{}) {
|
|
srcVal := reflect.ValueOf(src)
|
|
for _, target := range targets {
|
|
targetVal := reflect.ValueOf(target)
|
|
if targetVal.Kind() == reflect.Ptr {
|
|
targetVal = targetVal.Elem()
|
|
}
|
|
if targetVal.CanSet() && targetVal.Type() == srcVal.Type() {
|
|
targetVal.Set(srcVal)
|
|
}
|
|
}
|
|
}
|
|
|
|
func contains(slice interface{}, target interface{}) (found bool) {
|
|
sliceVal := reflect.ValueOf(slice)
|
|
targetType := reflect.TypeOf(target)
|
|
if sliceVal.Kind() == reflect.Slice && sliceVal.Type().Elem().Comparable() && targetType.Comparable() {
|
|
for i := 0; i < sliceVal.Len(); i++ {
|
|
if sliceVal.Index(i).Interface() == target {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func contains11(slice interface{}, target interface{}) (found bool) {
|
|
sliceVal := reflect.ValueOf(slice)
|
|
if sliceVal.Kind() == reflect.Slice {
|
|
for i := 0; i < sliceVal.Len(); i++ {
|
|
if reflect.DeepEqual(sliceVal.Index(i).Interface(), target) {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func convert12(src, target interface{}) (result interface{}, assigned bool) {
|
|
srcVal := reflect.ValueOf(src)
|
|
targetVal := reflect.ValueOf(target)
|
|
if srcVal.Type().ConvertibleTo(targetVal.Type()) {
|
|
result = srcVal.Convert(targetVal.Type()).Interface()
|
|
assigned = true
|
|
} else {
|
|
result = src
|
|
}
|
|
return
|
|
}
|
|
|
|
func IsInt(v reflect.Value) bool {
|
|
switch v.Kind() {
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
func IsFloat(v reflect.Value) bool {
|
|
switch v.Kind() {
|
|
case reflect.Float32, reflect.Float64:
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func convert13(src, target interface{}) (result interface{}, assigned bool) {
|
|
srcVal := reflect.ValueOf(src)
|
|
targetVal := reflect.ValueOf(target)
|
|
if srcVal.Type().ConvertibleTo(targetVal.Type()) {
|
|
if IsInt(targetVal) && IsInt(srcVal) && targetVal.OverflowInt(srcVal.Int()) {
|
|
Printfln("Int Overflow")
|
|
return src, false
|
|
} else if IsFloat(targetVal) && IsFloat(srcVal) && targetVal.OverflowFloat(srcVal.Float()) {
|
|
Printfln("Float Overflow")
|
|
return src, false
|
|
}
|
|
result = srcVal.Convert(targetVal.Type()).Interface()
|
|
assigned = true
|
|
} else {
|
|
result = src
|
|
}
|
|
return
|
|
}
|
|
|
|
func swap(first, second interface{}) {
|
|
firstValue, secondValue := reflect.ValueOf(first), reflect.ValueOf(second)
|
|
if firstValue.Type() == secondValue.Type() && firstValue.Kind() == reflect.Ptr && firstValue.Elem().CanSet() && secondValue.Elem().CanSet() {
|
|
temp := reflect.New(firstValue.Elem().Type())
|
|
temp.Elem().Set(firstValue.Elem())
|
|
firstValue.Elem().Set(secondValue.Elem())
|
|
secondValue.Elem().Set(temp.Elem())
|
|
}
|
|
}
|
|
|
|
func main1_6() {
|
|
product := Product{"Kayak", "Watersports", 279}
|
|
customer := Customer{"Alice", "New York"}
|
|
payment := Payment{"USD", 100.50}
|
|
|
|
// printDetails(product, customer)
|
|
printDetails1(product, customer)
|
|
|
|
printDetails2(product, customer, payment, 10, true)
|
|
|
|
printDetails3(product, customer, payment, 10, true)
|
|
|
|
number := 10
|
|
printDetails4(true, 10, 23.30, "Alice", &number, product)
|
|
|
|
printDetails5(true, 10, 23.30, "Alice", &number, product)
|
|
|
|
slice := []byte("Alice")
|
|
printDetails5(true, 10, 23.30, "Alice", &number, product, slice)
|
|
|
|
names := []string{"Alice", "Bob", "Charlie"}
|
|
val := selectValue6(names, 1).(string)
|
|
Printfln("Selected: %v", val)
|
|
}
|
|
|
|
func main7() {
|
|
name := "Alice"
|
|
price := 279
|
|
city := "London"
|
|
incrementOrUpper7(name, price, city)
|
|
for _, val := range []interface{}{name, price, city} {
|
|
Printfln("Value: %v", val)
|
|
}
|
|
}
|
|
|
|
func main8() {
|
|
name := "Alice"
|
|
price := 279
|
|
city := "London"
|
|
incrementOrUpper7(&name, &price, &city)
|
|
for _, val := range []interface{}{name, price, city} {
|
|
Printfln("Value: %v", val)
|
|
}
|
|
}
|
|
|
|
func main9() {
|
|
Printfln("\nmain9:")
|
|
name := "Alice"
|
|
price := 279
|
|
city := "London"
|
|
setAll9("New String", &name, &price, &city)
|
|
setAll9(10, &name, &price, &city)
|
|
for _, val := range []interface{}{name, price, city} {
|
|
Printfln("Value: %v", val)
|
|
}
|
|
}
|
|
|
|
func main10() {
|
|
Printfln("\nmain10:")
|
|
|
|
city := "London"
|
|
|
|
citiesSlice := []string{"Paris", "Rome", "London"}
|
|
Printfln("Found #1: %v", contains(citiesSlice, city))
|
|
|
|
sliceOfSlices := [][]string{citiesSlice, {"First", "Second", "Third"}}
|
|
Printfln("Found #2: %v", contains(sliceOfSlices, citiesSlice))
|
|
}
|
|
|
|
func main11() {
|
|
Printfln("\nmain11:")
|
|
|
|
city := "London"
|
|
|
|
citiesSlice := []string{"Paris", "Rome", "London"}
|
|
Printfln("Found #1: %v", contains11(citiesSlice, city))
|
|
|
|
sliceOfSlices := [][]string{citiesSlice, {"First", "Second", "Third"}}
|
|
Printfln("Found #2: %v", contains11(sliceOfSlices, citiesSlice))
|
|
}
|
|
|
|
func main12() {
|
|
Printfln("\nmain12:")
|
|
name := "Alice"
|
|
price := 279
|
|
|
|
newVal, ok := convert12(price, 100.00)
|
|
Printfln("Converted %v: %v, %T", ok, newVal, newVal)
|
|
newVal, ok = convert12(name, 100.00)
|
|
Printfln("Converted %v: %v, %T", ok, newVal, newVal)
|
|
}
|
|
|
|
func main13() {
|
|
Printfln("\nmain13:")
|
|
name := "Alice"
|
|
price := 279
|
|
|
|
newVal, ok := convert13(price, 100.00)
|
|
Printfln("Converted %v: %v, %T", ok, newVal, newVal)
|
|
newVal, ok = convert13(name, 100.00)
|
|
Printfln("Converted %v: %v, %T", ok, newVal, newVal)
|
|
|
|
newVal, ok = convert13(5000, int8(100))
|
|
Printfln("Converted %v: %v, %T", ok, newVal, newVal)
|
|
|
|
}
|
|
|
|
func main14() {
|
|
Printfln("\nmain14:")
|
|
name := "Alice"
|
|
price := 279
|
|
city := "London"
|
|
swap(&name, &city)
|
|
|
|
for _, val := range []interface{}{name, price, city} {
|
|
Printfln("Value: %v", val)
|
|
}
|
|
|
|
}
|