duankua3620 2018-04-10 11:39
浏览 99
已采纳

如何使用Go的类型别名使自己的模型与protobufs一起使用?

I've got some REST API with my models defined as Go structs.

type User struct {
  FirstName string
  LastName  string
}

Then I've got my database methods for getting data.

GetUserByID(id int) (*User, error)

Now I'd like to replace my REST API with https://github.com/twitchtv/twirp .

Therefore I started defining my models inside .proto files.

message User {
  string first_name = 2;
  string last_name = 3;
}

Now I've got two User types. Let's call them the native and the proto type.

I've also got a service defined in my .proto file which returns a user to the frontend.

service Users {
  rpc GetUser(Id) returns (User);
}

This generates an interface that I have to fill in.

func (s *Server) GetUser(context.Context, id) (*User, error) {
  // i'd like to reuse my existing database methods
  u, err := db.GetUserByID(id)
  // handle error
  // do more stuff
  return u, nil
}

Unfortunately this does not work. My database returns a native User but the interface requires a proto user.

Is there an easy way to make it work? Maybe using type aliases?

Thanks a lot!

  • 写回答

1条回答 默认 最新

  • duanniesui6391 2018-04-10 12:35
    关注

    One way you can solve your problem is by doing the conversion manually.

    type User struct {
        FirstName string
        LastName string
    }
    
    type protoUser struct {
        firstName string
        lastName string
    }
    
    func main() {
        u := db() // Retrieve a user from a mocked db
    
        fmt.Println("Before:")
        fmt.Printf("%#v
    ", *u) // What db returns (*protoUser)
        fmt.Println("After:")
        fmt.Printf("%#v
    ", u.AsUser()) // What conversion returns (User)
    }
    
    // Mocked db that returns pointer to protoUser
    func db() *protoUser {
        pu := protoUser{"John", "Dough"}
        return &pu
    }
    
    // Conversion method (converts protoUser into a User)
    func (pu *protoUser) AsUser() User {
        return User{pu.firstName, pu.lastName}
    }
    

    The key part is the AsUser method on the protoUser struct.
    There we simply write our custom logic for converting a protoUser into a User type we want to be working with.

    Working Example

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 stm32代码移植没反应
  • ¥15 matlab基于pde算法图像修复,为什么只能对示例图像有效
  • ¥100 连续两帧图像高速减法
  • ¥15 组策略中的计算机配置策略无法下发
  • ¥15 如何绘制动力学系统的相图
  • ¥15 对接wps接口实现获取元数据
  • ¥20 给自己本科IT专业毕业的妹m找个实习工作
  • ¥15 用友U8:向一个无法连接的网络尝试了一个套接字操作,如何解决?
  • ¥30 我的代码按理说完成了模型的搭建、训练、验证测试等工作(标签-网络|关键词-变化检测)
  • ¥50 mac mini外接显示器 画质字体模糊