试图找到这个perl数组的golang等价物

时间:2018-01-18 03:51:29

标签: go

我是一个学习go的perl脚本编写者。在perl中,可以轻松创建数组,而无需使用逗号和引号,如:

db.col.aggregate([
  {"$match":{"updatedAt":{"$exists":true}}},
  {"$sort":{"updatedAt":1}},
  {"$group":{
    "_id":null,
    "dates":{"$push":"$updatedAt"}
  }},
  {"$project":{
    "_id":0,
    "next":{
      "$let":{
        "vars":{
          "result":{
            "$reduce":{
              "input":{"$slice":["$dates",1,{"$subtract":[{"$size":"$dates"},1]}]},
              "initialValue":{"prev":{"$arrayElemAt":["$dates",0]},"last":{"$arrayElemAt":["$dates",0]},"diff":0},
              "in":{
                "$cond":[
                  {"$lt":["$$value.diff",{"$subtract":["$$this","$$value.prev"]}]},
                  {"prev":"$$this","last":"$$value.prev","diff":{"$subtract":["$$this","$$value.prev"]}},
                  "$$value"
                ]
              }
            }
          }
        },
        "in":{
          "$add":["$$result.last",{"$divide":["$$result.diff",2]}]
        }
      }
    }
  }}
])

golang是否提供这种简单性?或者我是否必须使用括号?

4 个答案:

答案 0 :(得分:2)

Go没有像Perl的qw那样的特殊语法,但你可以使用strings.Fields将字符串拆分成一串字符串:

    a := strings.Fields(`
      Hello 
      World 
      Won't 
      you 
      be 
      my 
      friend`)

Run it on the playground

惯用法是使用复合文字:

a := []string{"Hello", "World", "Won't", "you", "be", "my", "friend"}

答案 1 :(得分:2)

IMO,在Go中形成数组切片的唯一正确方法是:

slice := []string{"Hello", "World", "Won't", "you", "be", "my", "friend"}

这是创建字符串切片的标准方法。它是100%可读的。它没有任何意外。

通过比较,IMO,在Perl中形成该数组的唯一正确方法是:

my @array = ( "Hello", "World", "Won't", "you", "be", "my", "friend" );

qw运算符虽然在发起的Perl程序员中被广泛理解,但却不直观。是的,它允许您保存一些按键。但是代码应该是为了可读性而不是可写性而编写的。根据一些估计,大多数代码的读取次数比编写的多10倍。在某些情况下,它可能比其编写的数百或数千倍读取(想想核心库组件)。那么为什么你会牺牲可读性来节省一些击键?

即使您认为qw在Perl社区中被广泛理解以证明其在Perl中的使用(一个强有力的案例可以),这个论点肯定不会延续进入Go。去憎恶聪明的快捷方式,支持代码可读性。

当然“聪明”的选择,就像@CeriseLimón的回答中提供的那样,但它们会降低可读性。如果我在我正在阅读的某些代码中遇到strings.Fields那个上下文,它会中断读取代码的流程。我必须停下来思考“为什么作者使用它?这里的特殊情况是什么?为什么不能使用标准切片声明?”然后过了一两分钟,我可能会意识到“作者只是因为没有真正的理由而过于聪明.Pfft”,然后我必须备份我的代码阅读,并重新追踪我的步骤以重新获得流量

聪明是好的,可读的代码的敌人。

答案 2 :(得分:0)

我完全理解那些渴望@langs = qw(fortran pascal perl go)的人 - 这是我最常使用的Perl习语之一,因此完全清楚。

Go也值得简洁,但这是一个无法让编译器提供帮助的领域,必须在运行时完成。要为此付出代价。

e.g。

langs := strings.Split("fortran pascal perl go ...", " ")

try this

答案 3 :(得分:0)

Cerise Limón's answer所示,您可以使用strings.Fields(...)raw string literal来获得与Perl代码相似的样式/效果,无论是成语/最佳做法:

func main() {
    arr := strings.Fields(`
Hello
World
Won't
you 
be 
my 
friend
`)

    fmt.Printf("OK: arr=%q", arr)
    // OK: arr=["Hello" "World" "Won't" "you" "be" "my" "friend"]
}

是的,以上是what go fmt outputs =)