如何在不进行迭代的情况下打印指针切片以获取值而不是它们的地址?

时间:2019-01-22 06:02:27

标签: go slice

此类输出用于调试目的。 为了获取指针切片的实际值,每次需要进行迭代时。

有什么办法,我们可以使用简单的fmt.printf()直接获取值而不是切片中每个项目的地址?

这是一个代码段: https://play.golang.org/p/bQ5vWTlKZmV

package main

import (
    "fmt"
)

type user struct {
    userID int
    name   string
    email  string
}

func main() {
    var users []*user
    addUsers(users)
}

func addUsers(users []*user) {
    users = append(users, &user{userID: 1, name: "cooluser1", email: "cool.user1@gmail.com"})
    users = append(users, &user{userID: 2, name: "cooluser2", email: "cool.user2@gmail.com"})
    printUsers(users)
    printEachUser(users)

}

func printUsers(users []*user) {
    fmt.Printf("users at slice %v \n", users)
}

func printEachUser(users []*user) {
    for index, u := range users {
        fmt.Printf("user at user[%d] is : %v \n", index, *u)
    }
}

在上面的代码中,如果我直接通过fmt.printf打印切片,则仅获取值的地址,而不是实际值本身。

输出:users at slice [0x442260 0x442280]

要始终读取值,我必须像func一样调用printEachUser来迭代切片并获取适当的值。

输出: user at user[0] is : {1 cooluser1 cool.user1@gmail.com} user at user[1] is : {2 cooluser2 cool.user2@gmail.com}

有什么办法,我们可以使用fmt.printf读取指针切片内的值,并像下面一样直接获取值?

users at slice [&{1 cooluser1 cool.user1@gmail.com} , &{2 cooluser2 cool.user2@gmail.com}]

3 个答案:

答案 0 :(得分:2)

  

此类输出用于调试目的。

     

有什么办法,我们可以读取指针切片内的值   使用fmt.Printf并直接获得价值,如下所示?

users []*user
fmt.Printf("users at slice %v \n", users)

users at slice [&{1 cooluser1 cool.user1@gmail.com}, &{2 cooluser2 cool.user2@gmail.com}]

  

Package fmt

     

import "fmt"

     

type Stringer

     

Stringer由具有String方法的任何值实现,   定义该值的“本机”格式。使用String方法   打印作为操作数传递的值,使其接受任何格式   字符串或未格式化的打印机(例如“打印”)。

type Stringer interface {
        String() string
}

例如,

package main

import (
    "fmt"
)

type user struct {
    userID int
    name   string
    email  string
}

type users []*user

func (users users) String() string {
    s := "["
    for i, user := range users {
        if i > 0 {
            s += ", "
        }
        s += fmt.Sprintf("%v", user)
    }
    return s + "]"
}

func addUsers(users users) {
    users = append(users, &user{userID: 1, name: "cooluser1", email: "cool.user1@gmail.com"})
    users = append(users, &user{userID: 2, name: "cooluser2", email: "cool.user2@gmail.com"})

    fmt.Printf("users at slice %v \n", users)
}

func main() {
    var users users
    addUsers(users)
}

游乐场:https://play.golang.org/p/vDmdiKQOpqD

输出:

users at slice [&{1 cooluser1 cool.user1@gmail.com}, &{2 cooluser2 cool.user2@gmail.com}] 

答案 1 :(得分:1)

代码:https://play.golang.org/p/rBzVZlovmEc

输出:

  切片[{1 cooluser1 cool.user1@gmail.com}上的

个用户{2 cooluser2   cool.user2@gmail.com}]

使用纵梁可以达到目的。

引用:https://golang.org/pkg/fmt/#Stringer

testImplementation "org.robolectric:robolectric:4.1-SNAPSHOT" 

您无需对用户应用纵梁,即[] *用户,而仅对单个用户进行纵梁将可以正常工作。此外,它还减少了您需要手动执行的字符串操作,从而使代码更加美观。

答案 2 :(得分:0)

您可以使用spew

go get -u github.com/davecgh/go-spew/spew

func spewDump(users []*user) {
    _, err := spew.Printf("%v", users)
    if err != nil {
        fmt.Println("error while spew print", err)
    }
}

输出:

[<*>{1 cooluser1 cool.user1@gmail.com} <*>{2 cooluser2 cool.user2@gmail.com}]