小编icz*_*cza的帖子

Gob 无法使用 nil 指针值对映射进行编码

当我尝试将映射编码为指针(如果其中一个值为零)时,Gob 的编码会返回错误。这似乎与文档相矛盾(但我可能误解了含义):

在切片和数组以及映射中,所有元素(甚至零值元素)都会被传输,即使所有元素均为零。

代码:

package main

import (
    "bytes"
    "encoding/gob"
)

type Dog struct {
    Name string
}

func main() {
    m0 := make(map[string]*Dog)
    m0["apple"] = nil

    // Encode m0 to bytes
    var network bytes.Buffer
    enc := gob.NewEncoder(&network)
    err := enc.Encode(m0)
    if err != nil {
        panic(err) // Output: panic: gob: encodeReflectValue: nil element
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

panic: gob: encodeReflectValue: nil element
Run Code Online (Sandbox Code Playgroud)

在这种情况下,gob 失败有充分的理由吗?看来两个明显的选项中的任何一个都比失败更可取:1)不要使用零值的值对任何键进行编码,或者2)即使值是零值也对所有键进行编码。在目前的情况下,最佳实践是递归扫描我的结构以查看是否有任何 nil 映射值,如果有则删除这些键?如果需要进行此检查,则似乎应该由encoding/gob 包而不是用户负责。

此外,该规则不仅仅是“gob 无法对键值为 nil 的映射进行编码”,因为如果值类型是切片,则接受 nil:

func main() {
    m0 := make(map[string][]string)
    m0["apple"] = …
Run Code Online (Sandbox Code Playgroud)

pointers go gob

2
推荐指数
1
解决办法
1935
查看次数

键入断言接口,内部发生的事情

我很好奇当Go执行类型断言而另一个接口是其目标时,内部会发生什么.仅举例来说,请考虑Dave Cheney的博客中的这个例子:

type temporary interface {
    Temporary() bool
}

// IsTemporary returns true if err is temporary.
func IsTemporary(err error) bool {
        te, ok := err.(temporary)
        return ok && te.Temporary()
}
Run Code Online (Sandbox Code Playgroud)

我希望在这里发生很多运行时开销,因为它必须检查类型err并找出它是否具有所有方法.是这样,还是有一些聪明的魔法在下面发生?

methods interface go type-assertion

2
推荐指数
1
解决办法
91
查看次数

Protobuf,Go和私人领域

假设Player我的.proto文件已经定义了.

message Player {
  string first_name = 1;
  string last_name = 2;
  int32 user_id = 3;
}
Run Code Online (Sandbox Code Playgroud)

我正在使用https://github.com/twitchtv/twirp在我的Go后端和我的JavaScript前端之间进行通信.如果您不知道Twirp,它只是JSON RPC over HTTP 1.1.

Player消息被转换成细末结构

type Player struct {
  FirstName string
  LastName string
  UserId int32
}
Run Code Online (Sandbox Code Playgroud)

众所周知,大写字段是公开的.但是我想保持UserId私有,即将其设为小写.前端的用户不应该看到UserId播放器的用户.在我的后端,我需要这些信息,所以我不能简单地删除该字段.

任何想法如何处理这种情况?我的.proto文件中是否可以有私有字段?

struct go protocol-buffers

2
推荐指数
1
解决办法
343
查看次数

Golang 未设置结构域

在 Golang 中,我有以下三个字段的 Struct

type Person struct {
   name string
   age  int
   rank int
}
Run Code Online (Sandbox Code Playgroud)

对于处理,我需要一个等级字段,但对于输出,我想从结构中排除等级字段,因为我直接将上面的结构传递给 JSON 编码器以抛出响应。

有什么方法可以取消 Struct 中的排名字段?

json struct marshalling go

2
推荐指数
1
解决办法
2529
查看次数

哪个更好地获取Golang字符串的最后一个X字符?

当我有一个字符串"hogemogehogemogehogemoge世界世界世界"哪个代码更好,以避免内存分配得到最后的符文?

关于获取Golang String的最后X个字符有类似的问题.

如何获取Golang字符串的最后X个字符?

如果我只是想获得最后一个符文,我想确定哪个是首选的,没有任何额外的操作.

package main

import (
    "fmt"
    "unicode/utf8"
)

func main() {
    // which is more better for memory allocation?
    s := "hogemogehogemogehogemoge??????a"
    getLastRune(s, 3)
    getLastRune2(s, 3)
}

func getLastRune(s string, c int) {
    // DecodeLastRuneInString
    j := len(s)
    for i := 0; i < c && j > 0; i++ {
        _, size := utf8.DecodeLastRuneInString(s[:j])
        j -= size
    }
    lastByRune := s[j:]
    fmt.Println(lastByRune)
}

func getLastRune2(s string, c int) {
    // string -> []rune
    r := …
Run Code Online (Sandbox Code Playgroud)

string utf-8 go rune

2
推荐指数
1
解决办法
329
查看次数

有没有办法做 Sprintf 结果的逆运算

所以,我创建了一个字符串变量使用

name := "Batman"
age := 38
nameAndAge = fmt.Sprintf("%s %d", name, age)
Run Code Online (Sandbox Code Playgroud)

在另一个函数中,我可以访问变量nameAndAge。现在我想取回我在Sprintf. 我能想到的一种不经意的方法是根据分隔符拆分它并创建变量。我想知道是否有任何功能可以做到这一点?

喜欢,

var name string
var age int
// " " is the separator here
fmt.ReverseSprintf(nameAndAge, " ", name, age)
Run Code Online (Sandbox Code Playgroud)

谢谢您的帮助。

string printf go

2
推荐指数
1
解决办法
306
查看次数

Go 从字符串转换整数

最近在 leetcode 进行一些算法练习时,我遇到了一个解决方案,除了用户将字符串中的元素转换为整数的部分之外,我理解了所有内容,请看下面的代码。希望有人可以向我解释这一点。感谢您在 advnace 中的回复。

a := 234
b := strconv.Itoa(a)
c := int(b[0]-48) // why do we subtract 48?
Run Code Online (Sandbox Code Playgroud)

string go

2
推荐指数
1
解决办法
63
查看次数

我可以调整缓冲通道的大小吗?

我是 Golang 的新手,我可以像这样调整缓冲通道的大小:

var xxx // just declaration.

...

xxx = make(chan string, mysize)   // I know `xxx := make(chan string, mysize)` work, but I don't want it.

...

xxx <- "123" // using the buffered channel.
Run Code Online (Sandbox Code Playgroud)

concurrency channel go

2
推荐指数
1
解决办法
697
查看次数

fmt.Printf() 格式说明符以默认格式打印指向结构的指针?

我的代码:

package main

import (
    "fmt"
)

type Point struct {
    x int
    y int
}

func main() {
    fmt.Println(&Point{1, 2})
    fmt.Printf("%v\n", &Point{1, 2})
    fmt.Printf("%p\n", &Point{1, 2})
}
Run Code Online (Sandbox Code Playgroud)

输出:

&{1 2}
&{1 2}
0xc00002c070
Run Code Online (Sandbox Code Playgroud)

这与https://godoc.org/fmt中的文档不匹配。文档说,

%v 的默认格式是:

bool:                    %t
int, int8 etc.:          %d
uint, uint8 etc.:        %d, %#x if printed with %#v
float32, complex64, etc: %g
string:                  %s
chan:                    %p
pointer:                 %p
Run Code Online (Sandbox Code Playgroud)

根据上面的文档,对于指针, using%v应该像 using 一样%p

那么为什么 的输出fmt.Printf("%v\n", &Point{1, 2})与 的输出不匹配fmt.Printf("%p\n", …

struct pointers go format-specifiers

2
推荐指数
1
解决办法
134
查看次数

Mongodb 不会使用游标检索具有 200 万条记录的集合中的所有文档

我有 2,000,000 条记录的集合

> db.events.count();                                     ?
2000000             
Run Code Online (Sandbox Code Playgroud)

我使用 golang mongodb 客户端连接到数据库

> db.events.count();                                     ?
2000000             
Run Code Online (Sandbox Code Playgroud)

但是该程序仅检索大约 600,000 条记录,而不是每次我运行该程序时检索 2,000,000 条记录。

$ go run main.go
done
count = 605426
nErrors = 0
2020/09/18 11:23:43 End:         retrive db from mongo and publish to kafka took 10.080603336s
Run Code Online (Sandbox Code Playgroud)

我不知道为什么?我想检索所有 2,000,000 条记录。谢谢你的帮助。

go mongodb mongo-go

2
推荐指数
1
解决办法
253
查看次数