我今天开始学习Go。特别是,我一直在阅读文档http://blog.go-lang.org和http://golang-book.com。
学习语言有什么比练习语言更好的方法?我在Go中编写了一个小程序,它使用最少数量的硬币对客户进行更改。阅读了早期的指南后,似乎有很多方法可以在Go中做同样的事情。
例如:
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
}
非常感谢!
答案 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。
答案几乎完全取决于个人的应用需求。这里的示例程序很小,可以提供任何一般指导。局部变量通常比全局变量提供许多好处,但有时候全局变量更适合。
答案 2 :(得分:0)
是的,虽然根据我的个人经验,我从未在本地范围内看到它。 var ( ... )
语法传统上保留用于顶级声明(尽管我从未在任何样式指南中看到过这种情况;这只是我的观察结果)。
通常:=
没问题。当类型不明显,或者您希望变量不是明显的类型,或者甚至强制进行类型转换时,您通常希望将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
}
....
}
有时变量名称不足以传达你正在做的事情。
在声明一片硬币时,最好在函数中本地声明这些吗?
如果它是常数,请在外面声明。