我有一个树状结构,其中有字符串 regexp,我希望 Go 编译的 *regexp.Regexp 也成为其中的一部分,以便在树上运行算法。当我编码并将其传递到另一台机器时,我可能只是从字符串中再次重新编译它。正确的方法是什么,如何强制 protobuf 将指针存储在结构中,理想情况下它不会编码(marshal)? (我看到的唯一方法是创建 uint64
字段并将其值转换为 *Regexp
或从 *Regexp
转换)
伪代码(因为所需的功能似乎不在该语言中):
// struct generated by protoc
type ProtoMessage struct {
Data string
Source string
Regexp uint64 // should not be marshalled, should be forcefully omitted from payload when doing proto.Marshal, ideally it should be *regexp.Regexp
Left *ProtoMessage
Right *ProtoMessage
}
func main() {
// sender computer doSend():
mSrc := &ProtoMessage{Data:"its meee!!!", Source: "hello.+world"}
payload, _ := proto.Marshal(m)
//receiver computer: onRecv()
mDst := new(ProtoMessage)
proto.Unmarshal(payload, mDst)
r, _ := regexp.Compile(mDst.Source)
mDst.Regexp = uint64(unsafe.Pointer(r)) // not working btw
TreeMatch = func(tree* ProtoMessage, line string) string {
if *regexp.Regexp(t.Regexp).Match(line) { // not working line
return t.Data
}
if tree.Left == nil {
return ""
}
return TreeMatch(tree.Left, line)
}
assert( TreeMatch(mDst, "hello, world") == "its meee!!!") // panic if condition is false
}
使用 json marshal,我可以将一个指针指向正则表达式并提供一个标签 json:"-"
以便不将该字段包含到编码结构中,并且 ofc 是其编码/解码的重要功能系统保持高效(例如,使用相同的结构来运行算法,并避免解码后的数据复制)。我怎样才能用 protobuf 做同样的事情?
最佳答案
您无法将指针存储在 protobuf 中,因为接收者可能是另一台计算机。即使可以,当您尝试取消引用指针时,您也会感到 panic 。最简单的事情就是传递 RegExp 字符串,然后在目的地再次编译:
package main
import (
"fmt"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/structpb"
)
func main() {
v := structpb.NewStringValue("hello.+world")
b, err := proto.Marshal(v)
if err != nil {
panic(err)
}
fmt.Printf("%q\n", b) // "\x1a\fhello.+world"
}
注意:你也无法使用 Gob 来解决这个问题:
package main
import (
"bytes"
"encoding/gob"
"regexp"
)
func main() {
re := regexp.MustCompile("hello.+world")
buf := new(bytes.Buffer)
if err := gob.NewEncoder(buf).Encode(re); err != nil {
panic(err) // type regexp.Regexp has no exported fields
}
}
关于go - 如何将正则表达式放入golang的proto结构中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69003068/