草庐IT

go - 如何在 Go 中迭代自定义类型的数组?

coder 2024-07-14 原文

我在代码中创建了一个客户类型。我有一个函数正在读取 csv 文件并从每一行创建一个数组。

type DesiredService struct {
    Name string `json:"Name"`
    Status string `json:"Status"`
}

如果我打印出变量,我有一些看起来像 [{app1 active}{app2 active}]

我不知道如何使用该变量并遍历每个索引。我需要获取所有状态为事件的条目并调用另一个函数来根据 API 检查名称。我在想也许我没有正确设置结构。

当我检查变量类型时,它返回 []main.DesiredService

在阅读了一些文档之后,这是我想出的但行不通的方法。

func checkPagerDutyforService (serviceList []DesiredService) (bool){
    var serviceExist bool()
    for i, v := range serviceList {
        if v == "active" {
            checkIfServiceExist(i, serviceList)
            serviceExist = true
        } else {
            if v != "active"{
                serviceExist = false
            }
        }
    }
    return serviceExist

最佳答案

I need to take all of the entries with a Status of active and call another function to check the name against an API.

在 Go 中,您使用 for 进行迭代循环,通常使用 range功能。

package main

import (
    "fmt"
)

type DesiredService struct {
    // The JSON tags are redundant here. See below.
    Name string `json:"Name"`
    Status string `json:"Status"`
}

func main() {
    services := []DesiredService{
        DesiredService{"foo", "Active"},
        DesiredService{"bar", "Active"},
        DesiredService{"baz", "Inactive"},
    }

    for _,service := range services {
        if service.Status == "Active" {
            fmt.Printf("%#v\n", service);
        }
    }
}

请注意,range 返回索引(即 0、1、2)和实际元素。如果你只想要索引,它是 for i := range services 但如果你只想要元素,它是 for _,service := range services_ 告诉 Go 你不需要那个返回值。

range 是 Go 非常强大和灵活的核心特性。如果您还没有达到 range,我建议您至少停下来阅读 A Tour of GoGo By Example这将涵盖像这样的基本功能。然后阅读 Effective Go了解详情。


请注意,JSON 字段标签是不必要的。默认情况下,JSON 已经自动将字段 Name 编码为 JSON 字段 Name。所以它们可以省略。如果您想将其更改为 name,则需要使用标签。


您尝试的代码存在很多问题。

  • v == "active":v 是一个 DesiredService 结构。要检查其状态字段,它是 v.Status == "active"
  • else { if v != "active":这与 if v == "active" 是多余的。如果你在 else 定义的 block 中 v == "active"
  • return serviceExist:这是由每次循环迭代设置的,因此它只会反射(reflect) serviceList 中的最后一个元素。

这是您处理此问题的方式。

// Just a placeholder. Presumably it will ping the service
// to ensure it's really working.
func pingService( service DesiredService ) bool {
    return true
}

func getActiveService (services []DesiredService) *DesiredService {
    for _, service := range services {
        if service.Status == "active" && pingService(service) {
            return &service
        }
    }

    return nil
}

请注意,它会在找到事件服务后立即返回,而不是遍历整个列表。一旦找到服务,就无需再进行下一步。

出于两个原因,我已将其更改为 getActiveService。这里没有关于寻呼机的任何内容,因此大概它可以处理任何类型的服务列表。其次,返回一个 bool 就像说“是的,这个列表中有一个活跃的服务”,下一个自然的问题是“好吧,自作聪明,哪个?!”既然我们已经完成了工作,不妨返回一个活跃的服务。

这会将返回值从一个简单的 bool 值稍微更改为 *DesiredService。 “获取”功能有时无法获取您想要的内容。但是 DesiredService 类型表示您将总是返回一个DesiredService。通过使其成为 DesiredService 的引用,如果没有事件服务,我们可以返回 nil

service := getActiveService(services);
if service != nil {
    fmt.Println(service)
} else {
    fmt.Println("No active service")
}

*DesiredService 是对 DesiredService 的引用,而不是副本。 Go 将消除事物和事物引用之间的差异,没有用于处理引用的特殊语法。但是,请注意您使用的不是副本。您对 service 所做的任何更改都将反射(reflect)在 services 列表中。

// This will affect the entry in services as well.
service.Name = "something else"

Further detailed errors are returned using the error type .


下一步是将 service.Status == "active"&& pingService(service) 滚动到 a single method on DesiredService所以服务知道如何检查自己。然后任何使用 DesiredService 的人都不需要知道这些细节,而且如果细节发生变化,它们都在一个地方。

func (self DesiredService) isActive() bool {
    return self.Status == "active" && self.Ping()
}

Ping 也是服务应该对自己执行的操作。

// Just a placeholder. Presumably this will ping the
// service or something.
func (self DesiredService) Ping() bool {
    return true
}

然后 getActiveService 询问 service 是否激活。

func getActiveService (serviceList []DesiredService) *DesiredService {
    for _, service := range serviceList {
        if service.isActive() {
            return &service
        }
    }

    return nil
}

关于go - 如何在 Go 中迭代自定义类型的数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48693172/

有关go - 如何在 Go 中迭代自定义类型的数组?的更多相关文章

  1. ruby - 如何在 Ruby 中顺序创建 PI - 2

    出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits

  2. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  3. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  4. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  5. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  6. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  7. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

  8. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  9. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  10. ruby - 通过 erb 模板输出 ruby​​ 数组 - 2

    我正在使用puppet为ruby​​程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby​​不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这

随机推荐