Linux 在导入的包中定义结构时如何使用go receiver
目前正在使用Linux 在导入的包中定义结构时如何使用go receiver,linux,go,network-programming,netlink,Linux,Go,Network Programming,Netlink,目前正在使用vishvananda/netns包,试图从特定网络名称空间提取路由 有一个已定义的Handlestruct,在我请求特定网络名称空间的“Handle”时返回。因此: func NewHandleAt(ns netns.NsHandle,nlFamilies…int)(*句柄,错误) 这是需要该句柄的函数的接收方参数(?) func(h*Handle)LinkList()([]链接,错误) 我是新手,不知道如何把这些联系在一起。我被困在: func (h *Handle) showI
vishvananda/netns
包,试图从特定网络名称空间提取路由
有一个已定义的Handle
struct,在我请求特定网络名称空间的“Handle”时返回。因此:
func NewHandleAt(ns netns.NsHandle,nlFamilies…int)(*句柄,错误)
这是需要该句柄的函数的接收方参数(?)
func(h*Handle)LinkList()([]链接,错误)
我是新手,不知道如何把这些联系在一起。我被困在:
func (h *Handle) showInts() {
int, err := h.netlink.LinkList()
if err != nil {
log.Fatal(err)
}
for i, r := range int {
log.Printf("%d: %s", i, r.Attrs().Name)
}
}
func main() {
ints, err := netlink.LinkList()
if err != nil {
log.Fatal(err)
}
for i, r := range ints {
log.Printf("%d: %s", i, r.Attrs().Name)
}
pid, err := netns.GetFromPid(9097)
if err != nil {
log.Fatal(err)
}
netlink.NewHandleAt(pid)
showInts()
}
更新
在写原始答案时,涉及了很多东西,没有任何清晰的结构,因此这里有一个更结构化的版本:
根据您实际提出的问题(即“如何将接收器函数/方法添加到导出类型”或“接收器函数到底是什么”),答案如下:
如何向导出的类型添加接收器函数?
简单,和其他类型一样。事实上,你很接近。这不起作用:
func (h *Handler) showInts() {}
因为您正在向包中的处理程序
类型添加一个方法。如果你有一个main
函数,那就是main
包。您正在尝试将其添加到netlink.Handler
类型。在这种情况下,这将起作用:
func (h *netlink.Handler) showInts(){}
毕竟,主包中的类型是netlink.Handler
。。。然而,这是行不通的。编译器将拒绝编译,告诉您:“无法在非本地类型上定义新方法”。不过,通过创建一个新类型并在其中添加方法,可以轻松缓解这一问题:
type MyHandler netlink.Handler
func (h *MyHandler) showInts(){}
尽管如此,代码中的最后两行我认为是错的。
假设NewHandleAt
返回(*句柄,错误)
,并且netlink.Handle
是一个接收方参数,正确的方法是:
var mh *MyHandle
if h, err := netlink.NewHandleAt(pid); err != nil {
log.Fatal(err) // something went wrong
} else {
mh = (*MyHandle)(h)
}
mh.showInts() // call showInts on mh, which is of type *MyHandle
事实上,您已经将外部类型“包装”到自定义类型中,这确实意味着您将发现自己多次使用相同的类型。假设netlink.Handle
有一个Test
方法,您想在showInts
中调用它:
func (h *MyHandle) showInts() {
nh := (*netlink.Handle)(h) //cast required
nh.Test()
}
我还将varname从pid
更改为nsh
或其他什么,因为它是NsHandle
,而不是pid
什么是接收者参数? 因为你写了这个: 这是需要该句柄的函数的接收方参数(?) 我得到的印象是,你并不完全清楚什么是接受者论点。简单地说,它就像一个函数参数,但它不是一个刚刚传递给函数的参数,而是一个保存调用函数的对象/值的参数。基本上,它是调用函数/方法的“实例”。在许多OOP语言中,可以将其视为
这个
关键字:
func (h *MyHandle) showInts() {
return
}
在C++之类的东西中,p>
class MyHandle : Handle
{
public:
void showInts(void) { return; } // replace h with this
}
但是,存在显著差异:
- receiver参数可以是指针或值-对于值接收器,该方法无法修改接收器值
- 没有私人、公共或受保护的东西。。。至少不是以传统的面向对象的方式
其他问题/奇怪的事情 再次查看您的代码后,我真的不确定这是否正确:
h.netlink.LinkList()
在main
函数中,调用netlink.LinkList()
h
是一个*netlink.Handler
。如果您需要调用netlink.LinkList
函数,则很可能h.netlink.LinkList
不是您想要执行的操作。相反,您只需调用netlink.LinkList()
这是假设您首先需要调用函数 既然您已经在
main
函数中调用了它,为什么不将其作为参数传递呢
//in main:
ints, err := netlink.LinkList()
//...
h.showInts(ints)
func (h *MyHandle)showInts(ll []netlink.Link) {
}
谢谢Elias,真棒的回答 在此基础上,我编写了以下代码,其中列出了属于特定名称空间的接口。谢谢
package main
import (
"github.com/vishvananda/netns"
"github.com/vishvananda/netlink"
"log"
)
type NSHandle netlink.Handle
func (h *NSHandle) showInts() {
nh := (*netlink.Handle)(h) //cast required
int, err := nh.LinkList()
if err != nil {
log.Fatal(err)
}
log.Printf("Namespace Ints:")
for i, r := range int {
log.Printf("%d: %s", i, r.Attrs().Name)
}
}
func getNSFromPID(pid int) (*NSHandle) {
hpid, err := netns.GetFromPid(9115)
if err != nil {
log.Fatal(err)
}
var nsh *NSHandle
if h, err := netlink.NewHandleAt(hpid); err != nil {
log.Fatal(err) // something went wrong
} else {
nsh = (*NSHandle)(h)
}
return nsh
}
func main() {
getNSFromPID(9115).showInts()
}