英文:
Golang Parsing of ProtoBuf
问题
我是你的中文翻译助手,以下是你要翻译的内容:
我是Golang的新手,我正在尝试使用Micro框架和Protobuf框架编写一个家庭自动化框架。
我目前在尝试实现一个简单的注册表类型服务时遇到了困难。
我遇到的问题的一个例子是,我希望能够在客户端通过GET请求http://localhost:8080/view/devices
获取设备列表。
我有以下的Protobuf定义:
syntax = "proto3";
service DRegistry {
rpc View(ViewRequest) returns (DeviceRegistry) {}
}
message DeviceRegistry {
repeated Device devices = 1;
}
message ViewRequest {
string Alias = 1;
}
message Device {
string Alias = 1;
string HWAddress = 2;
string WakeUpMethod = 3;
repeated string BoundServices = 4;
}
然后在我的服务定义中,我有以下代码:
package main
import (
"log"
micro "github.com/micro/go-micro"
proto "github.com/srizzling/gotham/proto/device"
"golang.org/x/net/context"
)
// DRegistry stands for Device Registry and is how devices register to Gotham.
type DRegistry struct{}
var devices map[string]proto.Device
func (g *DRegistry) View(ctx context.Context, req *proto.ViewRequest, rsp *proto.DeviceRegistry) error {
filter := req.Alias
devices, err := filterDevices(filter)
rsp.Devices = devices
}
func filterDevices(filter string) (*[]proto.Device, error) {
// Currently only supports listing a single service for now
// TODO: expand filter to be more consise
filteredDevices := make([]proto.Device, 0, len(devices))
for _, e := range devices {
for _, f := range e.BoundServices {
if f == filter {
filteredDevices = append(filteredDevices, e)
}
}
}
return &filteredDevices, nil
}
func main() {
service := micro.NewService(
micro.Name("DRegistry"),
)
proto.RegisterDRegistryHandler(service.Server(), new(DRegistry))
if err := service.Run(); err != nil {
log.Fatal(err)
}
}
我遇到的问题是,我的IDE(Visual Studio Code)报错说“无法将devices(类型*[]device.Device)分配给[]*device.Device类型”,这让我感到困惑。
简而言之:我如何将一组proto.Devices分配给proto.DeviceRegistry?
英文:
I'm new to Golang and I am trying to write an home automation framework in Golang, using the Micro framework and Protobuf framework.
I am currently having a hard time trying to implement a simple registry type service.
An example of the problem I am having is that I have the following, I want to be able to get a list of devices, provided a client does a GET request to http://localhost:8080/view/devices
I have the following protobuf definition:
syntax = "proto3";
service DRegistry {
rpc View(ViewRequest) returns (DeviceRegistry) {}
}
message DeviceRegistry {
repeated Device devices = 1;
}
message ViewRequest {
string Alias = 1;
}
message Device {
string Alias = 1;
string HWAddress = 2;
string WakeUpMethod = 3;
repeated string BoundServices = 4;
}
Then in my service defination I have the following:
package main
import (
"log"
micro "github.com/micro/go-micro"
proto "github.com/srizzling/gotham/proto/device"
"golang.org/x/net/context"
)
// DRegistry stands for Device Registry and is how devices register to Gotham.
type DRegistry struct{}
var devices map[string]proto.Device
func (g *DRegistry) View(ctx context.Context, req *proto.ViewRequest, rsp *proto.DeviceRegistry) error {
filter := req.Alias
devices, err := filterDevices(filter)
rsp.Devices = devices
}
func filterDevices(filter string) (*[]proto.Device, error) {
// Currently only supports listing a single service for now
// TODO: expand filter to be more consise
filteredDevices := make([]proto.Device, 0, len(devices))
for _, e := range devices {
for _, f := range e.BoundServices {
if f == filter {
filteredDevices = append(filteredDevices, e)
}
}
}
return &filteredDevices, nil
}
func main() {
service := micro.NewService(
micro.Name("DRegistry"),
)
proto.RegisterDRegistryHandler(service.Server(), new(DRegistry))
if err := service.Run(); err != nil {
log.Fatal(err)
}
}
The problem I am having is that my IDE (Visual Studio Code) is complianing that I cannot use devices (type *[]device.Device) as type []*device.Device in assignment
which is confusing.
TLDR: How do I assign a collection of proto.Devices to the proto.DeviceRegistry?
答案1
得分: 3
func filterDevices(filter string) ([]*proto.Device, error) {
// 目前仅支持列出单个服务
// TODO: 扩展筛选条件以更简洁
filteredDevices := make([]*proto.Device, 0, len(devices))
for _, e := range devices {
for _, f := range e.BoundServices {
if f == filter {
filteredDevices = append(filteredDevices, &e)
}
}
}
return filteredDevices, nil
}
一个切片的指针([]*)和一个指向切片的指针(*[])之间是有区别的。你返回的是一个指向切片的指针,而你想要的是一个切片的指针。我们可以通过以下方式解决:
- 更新你的
filterDevices
函数签名,使其返回一个切片的指针 - 更新你的
make
调用,创建一个切片的指针 - 在调用
append
时取e
的地址(我们想要一个指向设备的切片的指针) - 不要返回切片的地址
英文:
func filterDevices(filter string) ([]*proto.Device, error) {
// Currently only supports listing a single service for now
// TODO: expand filter to be more consise
filteredDevices := make([]*proto.Device, 0, len(devices))
for _, e := range devices {
for _, f := range e.BoundServices {
if f == filter {
filteredDevices = append(filteredDevices, &e)
}
}
}
return filteredDevices, nil
}
There is a difference between a slice of pointers ([]*) and a pointer to a slice (*[]). You are returning a pointer to slice, whereas what you want is a slice of pointers. We can solve this by:
- Updating your
filterDevices
signature to return a slice of pointers - Updating your
make
call to make a slice of pointers - Taking the address of
e
in your call to append (we want a slice of pointers to devices) - Not returning the address of the slice
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论