给新手的建议去

时间:2013-08-04 19:41:59

标签: go

我今天开始学习Go。特别是,我一直在阅读文档http://blog.go-lang.orghttp://golang-book.com

学习语言有什么比练习语言更好的方法?我在Go中编写了一个小程序,它使用最少数量的硬币对客户进行更改。阅读了早期的指南后,似乎有很多方法可以在Go中做同样的事情。

例如:

  • 在单个var语句中声明多个变量是否可以?
  • 你应该使用var声明变量,还是使用:= okay?
  • 推断出类型
  • 在宣布一片硬币时,最好在函数中本地声明这些吗?

package main

import "fmt"

func main() {
    fmt.Printf("%v", change(158))
}

func change(value int) []int {
    var (
        change []int
        coins = []int{ 100, 50, 20, 10, 5, 2, 1 }
    )

    for value > 0 {
        for i := 0; i < len(coins); i++ {
            if coins[i] <= value {
                change = append(change, coins[i])
                value -= coins[i]
                break
            }
        }
    }

    return change
}

非常感谢!

4 个答案:

答案 0 :(得分:2)

有些事情只是风格问题。另外,考虑如果要求您扩展功能会发生什么,例如,支持多种货币作为货币包的一部分。例如,我会将change函数编写为货币的方法:

package main

import "fmt"

type Currency struct {
    Name  string
    Notes []int
    Coins []int
}

var ukCurrency = Currency{
    Name:  "UK Sterling",
    Notes: []int{5000, 2000, 1000, 500},
    Coins: []int{100, 50, 20, 10, 5, 2, 1},
}

var usCurrency = Currency{
    Name:  "US Dollar",
    Notes: []int{10000, 5000, 2000, 1000, 500, 100},
    Coins: []int{25, 10, 5, 1},
}

func (c *Currency) Change(amount int) []int {
    var change []int
    for _, note := range c.Notes {
        for note <= amount {
            change = append(change, note)
            amount -= note
        }
        if amount == 0 {
            break
        }
    }
    for _, coin := range c.Coins {
        for coin <= amount {
            change = append(change, coin)
            amount -= coin
        }
        if amount == 0 {
            break
        }
    }
    return change
}

func main() {
    for _, currency := range []Currency{ukCurrency, usCurrency} {
        fmt.Println(currency.Name, currency.Change(158))
        fmt.Println(currency.Name, currency.Change(4747))
    }
}

输出:

UK Sterling [100 50 5 2 1]
UK Sterling [2000 2000 500 100 100 20 20 5 2]
US Dollar [100 25 25 5 1 1 1]
US Dollar [2000 2000 500 100 100 25 10 10 1 1]

作为一种风格问题,我会将您的更改功能修改为:

package main

import "fmt"

var coins = []int{100, 50, 20, 10, 5, 2, 1}

func change(amount int) []int {
    var change []int
    for _, coin := range coins {
        for coin <= amount {
            change = append(change, coin)
            amount -= coin
        }
        if amount == 0 {
            break
        }
    }
    return change
}

func main() {
    fmt.Println(change(158))
}

答案 1 :(得分:0)

  • 在单个var语句中声明多个变量是否可以?

  • 您应该使用var声明变量,还是推断类型 使用:=好吗?

两者都可以接受。根据经验,如果您需要使用值初始化变量,则使用:=如果不是,则使用var。

  • 在宣布一片硬币时,最好在本地声明这些 在功能?

答案几乎完全取决于个人的应用需求。这里的示例程序很小,可以提供任何一般指导。局部变量通常比全局变量提供许多好处,但有时候全局变量更适合。

答案 2 :(得分:0)

  • 在单个var语句中声明多个变量是否可以?

是的,虽然根据我的个人经验,我从未在本地范围内看到它。 var ( ... )语法传统上保留用于顶级声明(尽管我从未在任何样式指南中看到过这种情况;这只是我的观察结果)。

  • 你应该使用var声明变量,还是使用:= okay?
  • 推断出类型

通常:=没问题。当类型不明显,或者您希望变量不是明显的类型,或者甚至强制进行类型转换时,您通常希望将var与显式类型一起使用。

例如,假设您有一个变量a,并且您想要制作一个重复变量b。有时您可能想提醒读者a的类型而不仅仅是b := a

作为“非显而易见”情况的一个例子,假设您需要一个16位浮点值。您可以执行以下任一操作,但有些人会考虑第二个清洁工:

a := float16(1)
var a float16 = 1

最后,使用var,您只需要声明,而不是分配变量(例如,使用其默认值,或稍后分配):

`var a int`
  • 在宣布一片硬币时,最好在函数中本地声明这些吗?

这主要取决于两个因素:它是否与函数逻辑相关,如果在本地声明,它是否足够大以致于麻烦?

显然,如果在其他函数中使用相同的值,您可能需要考虑全局声明它。有时,即使它仅在单个函数中使用,在全局声明它仍然更具逻辑性(例如,如果它感觉像是整个包的行为的参数,例如用于本地存储的字节数或类似的东西)。

即使它在逻辑上与本地函数相关,如果它是一个非常长的值,在本地声明它可能会显着混乱代码,这是全局声明它的正当理由:

func myFunc(){

//做一些事情

mySlice:= [] string {“1”,“2”,“3”,“4”,“5”,“6”,“7”,“8”,“9”,“10”, “11”,“12”,“13”,“14”,“15”,“16”,“17”,“18”,“19”,“20”,“21”,“22”,“23 “,”24“,”25“,”26“,”27“,”28“,”29“,”30“,”31“,”32“,”33“,”34“,”35“, “36”,“37”,“38”,“39”,“40”,“41”,“42”,“43”,“44”,“45”,“46”,“47”,“48 “,”49“,”50“,”51“,”52“,”53“,”54“,”55“,”56“,”57“,”58“,”59“,”60“, “61”,“62”,“63”,“64”,“65”,“66”,“67”,“68”,“69”,“70”,“71”,“72”,“73 “,”74“,”75“,”76“,”77“,”78“,”79“,”80“,”81“,”82“,”83“,”84“,”85“, “86”,“87”,“88”,“89”,“90”,“91”,“92”,“93”,“94”,“95”,“96”,“97”,“98” “,”99“,”100“,”101“,”102“,”103“,”104“,”105“,”106“,”107“,”108“,”109“,”110“, “111”,“112”,“113”,“114”,“115”,“116”,“117”,“118”,“119”,“120”,“121”,“122”,“123 “,”124“,”125“,”126“,”127“,”128“,”129“,”130“,”131“,”132“,”133“,”134“,”135“, “136”,“137”,“138”,“139”,“140”,“141”,“142”,“143”,“144”,“145”,“146”,“147”,“148 “,”149“,”150“,”151“,”152“,”153“,”154“,”155“, “156”,“157”,“158”,“159”,“160”,“161”,“162”,“163”,“164”,“165”,“166”,“167”,“168” “,”169“,”170“,”171“,”172“,”173“,”174“,”175“,”176“,”177“,”178“,”179“,”180“, “181”,“182”,“183”,“184”,“185”,“186”,“187”,“188”,“189”,“190”,“191”,“192”,“193” “,”194“,”195“,”196“,”197“,”198“,”199“,”200“,}

//做其他一些事情。

}

(请注意,我没有把它写成代码块,因为否则它不会被包裹起来,并且不会传达可能的丑陋。)

答案 3 :(得分:0)

我能给你的最好建议是:阅读内置软件包的源代码。源代码将为您提供极大的帮助。特别是在阅读一些便利功能时:他们做了什么让我的生活更轻松?另请注意以“_test.go”结尾的任何文件,因为它们将包含文档中未包含的示例。

  

在单个var语句中声明多个变量是否可以?

是的,只要它们是相关的。

  

你应该使用var声明变量,还是使用:= okay推断类型?在声明一片硬币时,最好是声明这些

要么有效。只是保持一致。有时,当函数已经声明了您正在使用的变量之一时,必须使用var预先声明变量:

func Foo() (err error) {
    ...
    var n int
    if n, err = something.Read(buf); err != nil {
        return
    }
    ....
}

有时变量名称不足以传达你正在做的事情。

  

在声明一片硬币时,最好在函数中本地声明这些吗?

如果它是常数,请在外面声明。