Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 在导入的包中定义结构时如何使用go receiver_Linux_Go_Network Programming_Netlink - Fatal编程技术网

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()
}