考虑这个包:
package A
var X="change me"
var Y=func(i int) int { return i*i) }
func Z(i int) int { return -i) }
两个显式变量(X,Y)可以在另一个包中更改,比如main ...
package main
import "A"
func main () {
A.X="done"
A.Y=func (i int) int { return i*i*i }
print(A.X,A.Y(7))
//... but A.Z apparently can't be changed.
//A.Z=func (int i) int { return i*i*i } //main.go:8: cannot assign to A.Z
}
显然,定义func变量(如Y)和显式func(如Z)之间存在差异。我用Google搜索了这一点,但在启蒙的方式中找不到多少。似乎var SomeFunc = func(...)确实定义了一个变量,但是func SomeFunc(...)定义了一个常量。
PS:我在研究这个时发现的一个小礼物,我在Go书中没有看到过,我到目前为止已经阅读过了。包导入之前的一个点导入名称,而不必对它们进行限定:package main
import . "A"
func main () {
X="done"
Y=func (i int) int { return i*i*i }
print(X,Y(7))
}
答案 0 :(得分:3)
func SomeFunc()
实质上创建了标识符SomeFunc
与您定义的函数的强/常量/不可变绑定。当你创建一个这样的变量时:
var (
SomeFunc = func(i int) int {
return i * 2
}
)
您创建了func(int) int
类型的全局变量。您可以稍后重新分配此变量。对于func SomeFunc
标识符,您无法真正做到这一点。简单地说,这是因为func SomeFunc()
将函数直接绑定到标识符。 var SomeFunc
方法创建一个变量(在这种情况下为func(int) int
),并使用您指定的函数初始化该变量。与变量的情况一样:可以重新分配。
你可以对函数做什么,是使用范围变量来遮蔽它们。这可能会被大多数短语所标记,但这是一种技术/技巧,有时可用于测试
至于dot-imports:请不要这样做,除非有非常非常非常的理由。一个很好的理由是你编写一个添加的包到现有的包中,所以你不再导入现有的包,而是导入你自己的包。可以将其视为扩展包。 99%的时间。不管怎样,在导入encoding/json
以将json序列化注释添加到结构时,不要使用它来解决错误。在这些情况下,请使用下划线:
package foo
import (
"encoding/json"
)
type Bar struct {
Foobar string `json:"foobar"`
}
func New() *Bar {
&Bar{"Default foobar"}
}
不知道golang 1.8,但是这样的包可能导致编译器错误(包编码/ json导入但未使用)。要消除该错误,您只需将导入更改为:
import(
_ "encoding/json"
)
点包,下划线和包别名都遵循相同的规则:尽可能少地使用它们。
示例中使用的代码:
package main
import (
"fmt"
)
var (
SomeFunc = func(i int) int {
return i * 2
}
)
func main() {
fmt.Println(SomeFunc(2)) // output 4
reassign()
fmt.Println(SomeFunc(2)) // output 8
shadowReassign()
fmt.Println(SomeFunc(2)) // output 2
}
// global function
func reassign() {
// assign new function to the global var. Function types MUST match
SomeFunc = func(i int) int {
return i * 4
}
}
// assign function to local reassign variable
func shadowReassign() {
reassign := func() {
// same as global reassign
SomeFunc = func(i int) int {
return i
}
}
reassign()
}
答案 1 :(得分:0)
声明使用函数值初始化的变量之间存在差异:
local fence = require("lib.fence")
local physics = require("physics")
local t = {}
local stages = {yellow = 1, lila = 1, red = 1}
local sizes = {1, 3.625, 7.25}
t.colors = {"yellow", "lila", "red"}
t.growing = false
t.setSize = function(fill)
local tHeight = fill.contentHeight * sizes[stages[fill.col]]
local tScale = tHeight / fill.contentHeight
fill.yScale = tScale
end
t.grow = function(group, color, hero)
local counter = 0
stages[color] = stages[color] + 1
for i = 1, group.numChildren, 1 do
if group[i].col == color then
counter = counter + 1
local function newPhysics() t.physics(group) end
if counter == 1 then
local function reset() t.growing = false if stages[color] == 3 then stages[color] = 1; newPhysics(); end end
local function start() t.growing = true end
transition.to(group[i], {time = 260, yScale = sizes[stages[color]], onStart = start, onComplete = reset})
else
transition.to(group[i], {time = 250, yScale = sizes[stages[color]], onStart = start})
end
end
end
end
t.physics = function(target)
if target.numChildren == nil then
physics.removeBody(target)
local function add()
physics.addBody( target, "static", {isSensor = true} )
target.collision = function(self, event)
if event.phase == "began" then
target.count = target.count + 1
if target.count == 1 then
t.grow(target.parent, self.col, event.other)
end
elseif event.phase == "ended" then
target.count = 0
end
end
end
timer.performWithDelay(1, add, 1)
else
for i = 1, target.numChildren, 1 do
physics.removeBody( target[i] )
physics.addBody( target[i], "static", {isSensor = true} )
target[i].name = "fill"
local fill = target[i]
fill.count = 0
fill.collision = function(self, event)
if event.phase == "began" then
self.count = self.count + 1
if self.count == 1 and event.other.x ~= nil then
t.grow(target, self.col, event.other)
end
else
fill.count = 0
end
end
fill:addEventListener("collision")
end
end
end
t.setColor = function(fill)
local colors = {
{238 / 255, 228 / 255, 28 / 255},
{38 / 255, 33 / 255, 77 / 255},
{175 / 255, 24 / 255, 52 / 255},
}
local names = {"yellow", "lila", "red"}
local r = math.random(3)
fill.fill = colors[r]
fill.col = names[r]
end
t.create = function(fences, group, colors)
local fills = {}
for i = 1, #fences, 1 do
local rCol = math.random(3)
local col
if rCol == 1 then
col = colors.yellow
elseif rCol == 2 then
col = colors.lila
else
col = colors.red
end
fills[i] = display.newRect(
group, fences[i].x + fences[i].contentWidth * 0.125, fences[i].y,
fences[i].contentWidth * 0.9, (fences[i].contentHeight * 0.5 / 3)
)
fills[i].dPosX = fills[i].x
fills[i].y = display.contentHeight- fills[i].contentHeight / 2
fills[i].fill = col
fills[i].col = t.colors[rCol]
fills[i].increased = false
end
return fills
end
t.move = function(fills, fences, group)
for i = 1, #fills, 1 do
local fill = fills[i]
function fill:enterFrame()
self:translate(fence.speed, 0)
if t.growing == false then
t.setSize(self)
end
if self.x > display.contentWidth + 0.55 * fences[i].contentWidth then
local xT = {}
for i = 1, group.numChildren, 1 do
xT[i] = group[i].x
end
local function compare(a, b) return a < b end
table.sort(xT, compare)
self.x = xT[1] - fences[i].contentWidth * 0.98
t.setColor(self)
local function newPhysics() t.physics(self) end
timer.performWithDelay( 25, newPhysics, 1 )
self:toBack()
end
end
Runtime:addEventListener("enterFrame", fill)
end
end
return t
并声明一个函数:
var Y=func(i int) int { return i*i) }
specification says this about declarations:
声明将非空标识符绑定到常量,类型,变量,函数,标签或包。
函数声明将标识符(函数名称)绑定到函数。
func Z(i int) int { return -i) }
的声明将变量绑定到名称。使用函数值初始化此变量。 Y
的声明将函数绑定到名称。
如果出现显式句点(。)而不是名称,则在该包的包块中声明的所有包的导出标识符将在导入源文件的文件块中声明,并且必须在没有限定符的情况下访问。