The following is an introduction to golang type assertions from the golang tutorial column. I hope it will be helpful to friends in need!
There is a serialize() function in php that can serialize the array into a string for storage and transmission.
If you want to deserialize this kind of string, you only need a simple function in php The unserialize() function can be completed. But it is not so easy in golang. It requires a lot of effort and writing a lot of code.
At this time I just want to sigh, php is really the best language in the world!
I encountered such a problem during today's development. I needed to use golang to parse PHP serialized strings. I found a parsing package on github, but found that the result after parsing was an interface{ }type.
I suddenly had no idea where to start. I always thought that the data was actually a map, but after parsing I got an interface{}. How should I use it?
I feel like I need to use type assertions. But I don’t know how to use it, so I went to the community and asked, hoping that the big guys can give me an answer.
It actually works really well.
Paste the code below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | package main
import (
"github.com/yvasiyarov/php_session_decoder/php_serialize"
"fmt"
"log"
)
func main() {
str := `a:3:{s:4: "name" ;s:3: "tom" ;s:3: "age" ;s:2: "23" ;s:7: "friends" ;a:2:{i:0;a:1:{s:4: "name" ;s:5: "jerry" ;}i:1;a:1:{s:4: "name" ;s:4: "jack" ;}}}`
decoder := php_serialize.NewUnSerializer(str)
if result, err := decoder.Decode(); err != nil {
panic(err)
} else {
decodeData, ok := result.(php_serialize.PhpArray)
if !ok {
log.Println(err)
}
name := decodeData[ "name" ]
age := decodeData[ "age" ]
fmt.Println(name, age)
friends, ok := decodeData[ "friends" ].(php_serialize.PhpArray)
if !ok {
log.Println(err)
}
for _,v := range friends {
fmt.Printf( "type:%T, value:%+v\n" , v,v )
friend, ok := v.(php_serialize.PhpArray)
if !ok {
log.Println(err)
}
friendName := friend[ "name" ]
fmt.Println(friendName)
}
}
}
|
Copy after login
It can be roughly understood like this: whatever type a variable is, what type of assertion is made. After the assertion, the result can be obtained
How to determine the type of a variable?
Print it out: fmt.Printf("%T", verb)
%T placeholder can display the type of the variable
There is another example below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | package main
import (
"github.com/yvasiyarov/php_session_decoder/php_serialize"
"fmt"
"log"
)
func main() {
str := `a:3:{s:4: "name" ;s:3: "tom" ;s:3: "age" ;s:2: "23" ;s:7: "friends" ;a:2:{i:0;a:1:{s:4: "name" ;s:5: "jerry" ;}i:1;a:1:{s:4: "name" ;s:4: "jack" ;}}}`
decoder := php_serialize.NewUnSerializer(str)
result, err := decoder.Decode()
if err != nil {
panic(err)
}
t := result.(php_serialize.PhpArray)
strVal := php_serialize.PhpValueString(t[ "name" ])
fmt.Println( strVal )
switch t := result.(type) {
default :
fmt.Printf( "unexpected type %T\n" , t)
case php_serialize.PhpArray:
fmt.Println(t)
fmt.Println(t[ "name" ])
fmt.Println(t[ "age" ])
switch f := t[ "friends" ].(type) {
default :
fmt.Printf( "unexpected type %T\n" , t)
case php_serialize.PhpArray:
fmt.Println(f)
fmt.Println(f[0])
fmt.Println(f[1])
}
}
}
|
Copy after login
Both the above two demos can achieve the effect, but they are written in different ways.
Later, I was introduced to another package, which also achieved the effect:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | package main
import (
"fmt"
"log"
"github.com/wulijun/go-php-serialize/phpserialize"
)
func main() {
str := `a:3:{s:4: "name" ;s:3: "tom" ;s:3: "age" ;s:2: "23" ;s:7: "friends" ;a:2:{i:0;a:1:{s:4: "name" ;s:5: "jerry" ;}i:1;a:1:{s:4: "name" ;s:4: "jack" ;}}}`
decodedRes, err := phpserialize.Decode(str)
if err != nil {
panic(err)
}
decodedData, ok := decodedRes.(map[ interface {}] interface {})
if !ok {
fmt.Printf( "unexpected type %T\n" , decodedRes)
}
fmt.Println(decodedData[ "name" ])
fmt.Println(decodedData[ "age" ])
friendsRes, ok := decodedData[ "friends" ].(map[ interface {}] interface {})
if !ok {
fmt.Printf( "unexpected type %T\n" , decodedData[ "friends" ])
}
for _,v := range friendsRes {
friend, ok := v.(map[ interface {}] interface {})
if !ok {
fmt.Printf( "unexpected type %T\n" , decodedData[ "friends" ])
}
fmt.Println(friend[ "name" ])
}
}
|
Copy after login
The types of all the results parsed by this package are map[interface{}]interface{ }, so you can be simpler and more crude when making type assertions.
The above is the detailed content of Learn about golang type assertions. For more information, please follow other related articles on the PHP Chinese website!