Golang:如何将指针附加到切片中的切片?

huangapple go评论84阅读模式
英文:

Golang: How to append pointer to slice to slice?

问题

我是一个 Golang 新手,但我认为我已经理解了指针和引用的基本知识,但显然并不是这样:

我有一个必须返回 []github.Repository 的方法,这是 Go 中 Github 客户端的一种类型。

API 调用返回分页结果,所以我必须循环直到没有更多结果,并将每次调用的结果添加到 allRepos 变量中,并返回 。以下是我目前的代码:

func (s *inmemService) GetWatchedRepos(ctx context.Context, username string) ([]github.Repository, error) {
    s.mtx.RLock()
    defer s.mtx.RUnlock()

    opt := &github.ListOptions{PerPage: 20}

    var allRepos []github.Repository

    for {
        // repos 是 *[]github.Repository 类型
        repos, resp, err := s.ghClient.Activity.ListWatched(ctx, "", opt)

        if err != nil {
            return []github.Repository{}, err
        }

        // 错误:无法将 repos(类型为 []*github.Repository)用作类型 github.Repository
        // 但是解引用也不起作用
        allRepos = append(allRepos, repos...)
        if resp.NextPage == 0 {
            break
        }
        opt.Page = resp.NextPage
    }

    return allRepos, nil
}

我的问题是:我如何将每次调用的结果追加到一个类型为 []github.Repository 的结果中并返回?

另外,为什么这里解引用不起作用?我尝试用 allRepos = append(allRepos, *(repos)...) 替换 allRepos = append(allRepos, repos...),但是我得到了这个错误信息:

Invalid indirect of (repos) (type []*github.Repository)
英文:

I'm a Golang newbie but I thought I had got the essentials of pointers and references straight, but apparently not:

I have a method that must return a []github.Repository, which is a type from the Github client in go.

The API call returns the results paginated so I must cycle until there's no more results, and add the result of each call to the allRepos variable, and return that. Here's what I have so far:

func (s *inmemService) GetWatchedRepos(ctx context.Context, username string) ([]github.Repository, error) {
	s.mtx.RLock()
	defer s.mtx.RUnlock()

	opt := &github.ListOptions{PerPage: 20}

	var allRepos []github.Repository

	for {
        // repos is of type *[]github.Repository
		repos, resp, err := s.ghClient.Activity.ListWatched(ctx, "", opt)

		if err != nil {
			return []github.Repository{}, err
		}
   
        // ERROR: Cannot use repos (type []*github.Repository) as type github.Repository
        // but dereferencing it doesn't work, either
		allRepos = append(allRepos, repos...)
		if resp.NextPage == 0 {
			break
		}
		opt.Page = resp.NextPage
	}

	return allRepos, nil

}

My question: how can I append the results of each call and return a result of type []github.Repository?

Also, why doesn't dereferencing work here? I've tried replacing allRepos = append(allRepos, repos...) with allRepos = append(allRepos, *(repos)...) but I get this error message:

Invalid indirect of (repos) (type []*github.Repository)

答案1

得分: 5

好的,以下是翻译好的内容:

嗯,这里有些问题:

你在注释中说“repos 的类型是 *[]github.Repository”,但编译器的错误信息表明 repos 的类型是 []*Repository。编译器从来不会(除非有错误)出错。

请注意,*[]github.Repository[]*Repository 是完全不同的类型,特别是第二个类型 不是 Repositories 的切片,而且你 不能(真的,没有办法)在 append() 中解引用这些指针:你必须编写一个循环,逐个解引用切片项并逐个追加。

另一个奇怪的地方是:github.RepositoryRepository 似乎是两个不同的类型,一个来自 github 包,另一个来自当前包。再次,你需要搞清楚这一点。

请注意,在 Go 语言中没有引用。立即停止思考这个概念:这是其他语言中的一个概念,在 Go 中是不存在的,也没有帮助。

英文:

Well, something is not okay here:

You say in the comment that "repos is of type *[]github.Repository" but the compiler's error message indicates that repos is of type []*Repository". The compiler is never (except when buggy) wrong.

Note that *[]github.Repository and []*Repository are completely different types, especially the second is not a slice of Repositories and you cannot (really, there is no way) dereference these pointers during append(): You have to write a loop and dereference each slice item and append one by one.

What is strange too: github.Repository and Repository seem to be two different types one from package github, the other from the current package. Again, you'll have to get that straight too.

Note that there are no references in Go. Stop thinking about these immediately: This is a concept from other languages which is not helpful (as inexistent) in Go.

答案2

得分: 1

在你的示例中,解引用是不正确的。你应该这样写:

allRepos = append(allRepos, *repos...)

这里是一个简单的示例,演示了解引用指向字符串切片的指针。https://play.golang.org/p/UDzaG5z8Pf

英文:

In your example the dereferencing is not correct. You should make it like this:

allRepos = append(allRepos, *repos...)

Here a simple example with dereferencing a pointer to a slice of string. https://play.golang.org/p/UDzaG5z8Pf

huangapple
  • 本文由 发表于 2017年3月20日 18:05:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/42900701.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定