diff --git a/27-reflection/reflection/main.go b/27-reflection/reflection/main.go index 3db8ece..036b6a0 100644 --- a/27-reflection/reflection/main.go +++ b/27-reflection/reflection/main.go @@ -11,4 +11,9 @@ func main() { main12() main13() main14() + + main15() + main16() + main17() + main18() } diff --git a/27-reflection/reflection/re2.go b/27-reflection/reflection/re2.go new file mode 100644 index 0000000..56f889c --- /dev/null +++ b/27-reflection/reflection/re2.go @@ -0,0 +1,120 @@ +package main + +import ( + "reflect" + "strings" +) + +func createPointerType(t reflect.Type) reflect.Type { + return reflect.PointerTo(t) +} + +func followPointerType(t reflect.Type) reflect.Type { + if t.Kind() == reflect.Ptr { + return t.Elem() + } + return t +} + +func main15() { + Printfln("\nmain15:") + name := "Alice" + + t := reflect.TypeOf(name) + Printfln("Original Type: %v", t) + + pt := createPointerType(t) + Printfln("Pointer Type: %v", pt) + Printfln("Pointer Type: %v", followPointerType(pt)) +} + +var stringPtrType = reflect.TypeOf((*string)(nil)) + +func transformString(val interface{}) { + elemValue := reflect.ValueOf(val) + if elemValue.Type() == stringPtrType { + if elemValue.CanAddr() { + Printfln("Can address pointer addr: %v", elemValue.Addr()) + } + elem := elemValue.Elem() + if elem.CanAddr() { + Printfln("Can address Follow pointer addr: %v", elem.Addr()) + } + upperStr := strings.ToUpper(elem.String()) + if elem.CanSet() { + elem.SetString(upperStr) + } + } +} + +func main16() { + Printfln("\nmain16:") + + name := "Alice" + transformString(&name) + Printfln("Follow pointer value: %v addr: %p", name, &name) + +} + +func checkElemType(val interface{}, arrOrSlice interface{}) bool { + elemType := reflect.TypeOf(val) + arrOrSliceType := reflect.TypeOf(arrOrSlice) + + return (arrOrSliceType.Kind() == reflect.Array || + arrOrSliceType.Kind() == reflect.Slice) && + arrOrSliceType.Elem() == elemType +} + +func main17() { + Printfln("\nmain17:") + + name := "Alice" + city := "London" + hobby := "Running" + + slice := []string{name, city, hobby} + array := [3]string{name, city, hobby} + + Printfln("Slice (string): %v", checkElemType("testString", slice)) + Printfln("Array (string): %v", checkElemType("testString", array)) + Printfln("Slice (int): %v", checkElemType(10, slice)) +} + +func setValue(arrayOrSlice interface{}, index int, replacement interface{}) { + arrayOrSliceVal := reflect.ValueOf(arrayOrSlice) + replacementVal := reflect.ValueOf(replacement) + if arrayOrSliceVal.Kind() == reflect.Slice { + elemVal := arrayOrSliceVal.Index(index) + if elemVal.CanSet() { + elemVal.Set(replacementVal) + } + } else if arrayOrSliceVal.Kind() == reflect.Ptr && + arrayOrSliceVal.Elem().Kind() == reflect.Array && + arrayOrSliceVal.Elem().CanSet() { + elemVal := arrayOrSliceVal.Elem().Index(index) + if elemVal.CanSet() { + elemVal.Set(replacementVal) + } + } +} + +func main18() { + Printfln("\nmain17:") + + name := "Alice" + city := "London" + hobby := "Running" + + slice := []string{name, city, hobby} + array := [3]string{name, city, hobby} + + Printfln("Original slice:%v", slice) + newCity := "Paris" + setValue(slice, 1, newCity) + Printfln("Modified slice:%v", slice) + + Printfln("Original array:%v", array) + newCity = "Rome" + setValue(&slice, 1, newCity) + Printfln("Modified array:%v", array) +} diff --git a/27-reflection/reflection/types.go b/27-reflection/reflection/types.go index 3a988d0..3757f2b 100644 --- a/27-reflection/reflection/types.go +++ b/27-reflection/reflection/types.go @@ -13,3 +13,10 @@ type Payment struct { Currency string Amount float64 } + +type Purchase struct { + Product + Customer + Total float64 + taxRate float64 +}