分类: Web开发
2013-02-03 00:17:11
Go allows you to define a struct that has fields but with no variable names. These fields are called anonymous fields. Let’s do a few examples to find out what they are and how they will be useful.
你可以定义一个结构体 这个结构体的字段可以没有变量的名字 只有类型 这些字段被称作是匿名字段
In the below example, we have defined a Kitchen struct, which only contains the number of plates as a field. We define another field called House, which contains an instance of Kitchen as a field - but it is an anonymous field, because we have not given a variable name for it.
下面这个例子中 我们定义了Ktchen结构体 它只包含一个字段 就是numOfPlates 我们定义另一个结构体House House包含Kitchen实例 但是它是一个匿名的字段 因为这个字段没有对应的变量的名字 只有类型
package main import "fmt"
type Kitchen struct {
numOfPlates int
}
type House struct {
Kitchen //anonymous field
numOfRooms int
}
func main() {
h := House{Kitchen{10}, 3} //to initialize you have to use composed type name.
fmt.Println("House h has this many rooms:", h.numOfRooms) //numOfRooms is a field of House
fmt.Println("House h has this many plates:", h.numOfPlates) //numOfPlates is a field of anonymous field Kitchen, so it can be referred to like a field of House
fmt.Println("The Kitchen contents of this house are:", h.Kitchen) //we can refer to the embedded struct in its entirety by referring to the name of the struct type
}
The first important thing to note is that since we have defined Kitchen to be an anonymous field, it allows us to access its members as if they were members of the encompassing class. In comparison, if you were using a language like Java, you would have to do:
有几个值得注意的地方 首先 由于我们定义一个匿名的字段Kitchen go允许我们直接访问Kitchen结构体中的字段 numOfPlates就如同House中的字段一样 如果你有java经验 那么可以参考以下这段代码 :
public class Kitchen {
public int numOfPlates;
}
public class House {
public Kitchen kitchen;
} //and in main
public static void main(String[] args) {
House h = new House();
h.kitchen.numOfPlates = 10; //referred as a sub field item.
}
The second important thing to note is that the composed field is still available to be accessed, but by its type name. So in this case the anonymous field for Kitchen has to be accessed ash.Kitchen. If you want to print the number of plates in the kitchen, then do this:fmt.Println(h.Kitchen.numOfPlates).
其次 我们可以通过被包含的结构体的类型名字 来访问这个被包含的结构体中的字段 h.Kitchen.numOfPlates
And the third important thing to note is how we had to use the type name when initializing the values as we did: h := House{Kitchen{10}, 3}. It is necessary here that you state the type name and provide its values within the corresponding curly braces. So h := House{{10}, 3}and h := House{10, 3} will cause compilation errors.
最后 当我们初始化House的时候 我们必须使用Kitchen类型名来初始化相应的匿名字段 所以像 h := House{{10}, 3} 或者 h := House{10, 3}方式来初始化House会导致编译错误
What happens when more than one of the composed structs or the composing struct has the same field name. If there is a field in an outer struct with the same name as a field in an inner anonymous struct, then the outer one is accessible by default. In the below example, both theKitchen and the House has a numOfLamps field, but since House is the outer struct, its numOfLamps hides Kitchen’s. If you still require to access the Kitchen’s numOfLamps, that is possible by referring to it via the type name: h.Kitchen.numOfLamps.
结构体可以包含多个字段 每个地段可能都是一个结构体 那么问题就就来了 这样会导致外层的定义会覆盖掉内层的定义 哎 一如既往的费脑啊 翻译不得体 那个例子来说事儿吧 下面这个例子中 Kitchen House都有numOfLamps字段 但是由于House是外层的结构提 它遮盖住了内层Kitchen的对应同名的字段 如果想要访问Kitchen中的字段 那么就需要使用 h.Kitchen.numOfLamps了
package main
import "fmt"
type Kitchen struct {
numOfLamps int
}
type House struct {
Kitchen
numOfLamps int
}
func main() {
h := House{Kitchen{2}, 10} //kitchen has 2 lamps, and the House has a total of 10 lamps
fmt.Println("House h has this many lamps:", h.numOfLamps) //this is ok - the outer House's numOfLamps hides the other one. Output is 10.
fmt.Println("The Kitchen in house h has this many lamps:", h.Kitchen.numOfLamps) //we can still reach the number of lamps in the kitchen by using the type name h.Kitchen
}
So there is a rule on field resolution when the same field occurs at different levels of composition. But there is no rule when the fields are at the same level of composition - which means that when it occurs you need to resolve it yourself.
go提供这个字段解析的方式 但是只对不同层次的组合出现重名的情况有作用 如果重名出现在同一层次里 那么这个就需要你亲自出马解决啦
In the code below, both the Kitchen and the Bedroom have a field numOfLamps, and both are available as an anonymous field within House. Now if we referred to House.numOfLamps, the Go compiler cannot resolve whether you are referring to the numOfLamps within Kitchen or that within Bedroom and it throws an error.
下面这个例子中House有两个匿名字段 而且在这两个匿名字段类型中包含相同的字段名 numOfLamps 如果还是像上面那个例子中那样通过h.numOfLamps来访问 那么go就傻了 你需要明确地告诉go 你要哪个女人
package main
import "fmt"
type Kitchen struct {
numOfLamps int
}
type Bedroom struct {
numOfLamps int
}
type House struct {
Kitchen
Bedroom
}
func main() {
h := House{Kitchen{2}, Bedroom{3}} //kitchen has 2 lamps, Bedroom has 3 lamps
fmt.Println("Ambiguous number of lamps:", h.numOfLamps) //this is an error due to ambiguousness - is it Kitchen.numOfLamps or Bedroom.numOfLamps
}
To resolve this, you will have to refer to the required fields explicitly via the type name of the anonymous field. In the corrected example below, we’ve summed up the number of lamps in the kitchen and the bedroom by referring to the number of lamps in it via its type name.
可以通过h.Kitchen.numOfLamps, h.Bedrom.numOfLamps来访问相应的numOfLamps
package main
import "fmt"
type Kitchen struct {
numOfLamps int
}
type Bedroom struct {
numOfLamps int
}
type House struct {
Kitchen
Bedroom
}
func main() {
h := House{Kitchen{2}, Bedroom{3}}
fmt.Println("House h has this many lamps:", h.Kitchen.numOfLamps + h.Bedroom.numOfLamps) //refer to fields via type name
}