如何从Golang中的接口中获取值

huangapple go评论105阅读模式
英文:

how to get values from a interface in golang

问题

我需要从一个由PHP代码生成的序列化字符串中获取值。

所以我使用了一个名为php_serialize的包来反序列化字符串,然后得到了一个interface{}类型的结果。

但是我不知道如何获取结果中的值。

以下是代码:

package main

import (
    "github.com/yvasiyarov/php_session_decoder/php_serialize"
    "fmt"
)

func main() {
    // 这个字符串是由PHP代码生成的
    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 {
        fmt.Println(result)
    }
}

打印结果为:

map[name:tom age:23 friends:map[0:map[name:jerry] 1:map[name:jack]]]

这个结果是php_serialize.PhpValue类型,也就是interface{}类型。

下一步是如何获取结果中的值?

比如获取age字段和对应的值。

英文:

I need to get values from a serialized string which generated from php code

So I use a package named:php_serialize to unserialize the string and then got a result of interface{} type .

But I have no idea how to get values inside the result.

This is code:

package main

import (
    "github.com/yvasiyarov/php_session_decoder/php_serialize"
    "fmt"
)

func main() {
    // this string is generated from php code
    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 {
	    fmt.Println(result)
    }
}

The print result is :

map[name:tom age:23 friends:map[0:map[name:jerry] 1:map[name:jack]]]

This result is a php_serialize.PhpValue type, which is interface{} type

The next step is how to get values inside the result?

such as get the age field and value

答案1

得分: 4

你必须将result断言为map[string]interface{}类型:

mResult := result.(map[string]interface{})
fmt.Println(mResult["name"])

然后再次对friends进行断言:

mFriends := mResult["friends"].(map[int]map[string]interface{})

然后使用它:mFriends[0]["name"]

英文:

You must assert the result to map[string]interface:

mResult := result.(map[string]interface{})
fmt.Println(mResult["name"])

And once more assertion for friends:

mFriends := mResult["friends"].(map[int]map[string]interface{}) 

Then use it: mFriends[0]["name"]

答案2

得分: 1

以下是访问数据的一些方法:

package main

import (
	"fmt"

	"github.com/yvasiyarov/php_session_decoder/php_serialize"
)

func main() {
	// this string is generated from php code
	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)
	}
	fmt.Println(result)

	// simple assert
	t := result.(php_serialize.PhpArray)
	// use php_serialize built-in function to get string
	strVal := php_serialize.PhpValueString(t["name"])
	fmt.Println(strVal)

	// type switch in case of different valid types
	switch t := result.(type) {
	default:
		fmt.Printf("unexpected type %T\n", t) // %T prints whatever type t has
	case php_serialize.PhpArray:
		fmt.Println(t)
		fmt.Println(t["name"])
		fmt.Println(t["age"])

		// should be done recursively...
		switch f := t["friends"].(type) {
		default:
			fmt.Printf("unexpected type %T\n", f) // %T prints whatever type t has
		case php_serialize.PhpArray:
			fmt.Println(f)
			fmt.Println(f[0])
			fmt.Println(f[1])
		}
	}
}

希望这能给你一些思路。

基本概念

  • php_serialize有内置函数用于转换基本类型。
  • 变量结构使用内置类型表示,需要使用这些类型来访问结构。
英文:

Here some ways to access the data:

package main

import (
	"fmt"

	"github.com/yvasiyarov/php_session_decoder/php_serialize"
)

func main() {
	// this string is generated from php code
	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)
	}
	fmt.Println(result)

	// simple assert
	t := result.(php_serialize.PhpArray)
	// use php_seriale build in function to get string
	strVal := php_serialize.PhpValueString(t["name"])
	fmt.Println(strVal)

	// type switch in case of different valid types
	switch t := result.(type) {
	default:
		fmt.Printf("unexpected type %T\n", t) // %T prints whatever type t has
	case php_serialize.PhpArray:
		fmt.Println(t)
		fmt.Println(t["name"])
		fmt.Println(t["age"])

		// should be done recursively...
		switch f := t["friends"].(type) {
		default:
			fmt.Printf("unexpected type %T\n", f) // %T prints whatever type t has
		case php_serialize.PhpArray:
			fmt.Println(f)
			fmt.Println(f[0])
			fmt.Println(f[1])
		}
	}
}

I hope this gives you some ideas.

Basic concept

  • php_serialize has built in functions to convert primitives.
  • Variable structures are represented with built in types which need to be used to access the structure.

huangapple
  • 本文由 发表于 2017年8月16日 13:49:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/45705930.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定