# 4.5.2-1 全局作用域

简单地说，该部分的任务就是将语言的[内置符号](/golang-bian-yi-qi-lei-xing-jian-cha/4.3-fu-hao-jie-xi.md)初始化，并注册到[全局作用域](/golang-bian-yi-qi-lei-xing-jian-cha/4.4.1-shu-ju-jie-gou-zuo-yong-yu.md)中。初始化逻辑在`$GCROOT/compile/internal/types2/universe.go`中，通过`init`函数在编译器启动时自动初始化：

```go
func init() {
	Universe = NewScope(nil, nopos, nopos, "universe") // 实例化全局作用域
	Unsafe = NewPackage("unsafe", "unsafe")
	Unsafe.complete = true

	defPredeclaredTypes()
	defPredeclaredConsts()
	defPredeclaredNil()
	defPredeclaredFuncs()
	defPredeclaredComparable()

	universeIota = Universe.Lookup("iota").(*Const)
	universeByte = Universe.Lookup("byte").(*TypeName).typ.(*Basic)
	universeRune = Universe.Lookup("rune").(*TypeName).typ.(*Basic)
	universeAny = Universe.Lookup("any").(*TypeName).typ.(*Interface)
	universeError = Universe.Lookup("error").(*TypeName).typ.(*Named)

	// "any" is only visible as constraint in a type parameter list
	delete(Universe.elems, "any")
}
```

该函数很清晰地表达了整个初始化过程，我们知道`Scope`中存放的是`Object`对象，所以各初始化函数的任务就是创建不同类型的`Object`对象并注册到全局变量`Universe`中。我们简单描述一下各个函数的任务：

* defPredeclaredTypes\
  &#x20;注册基本类型，例如 int8, float32, bool 等，包括前文提到的 Untyped 类型，该函数会为每种类型创建一个`TypeName`类型的 Object 对象。\
  \
  值得注意的是该方法还初始化了 error 类型，初始化代码如下：

```go
{
    res := NewVar(nopos, nil, "", Typ[String])                                // 方法返回类型为 string
    sig := &Signature{results: NewTuple(res)}                                 // 函数类型，只有返回 Tuple, 没有参数 Tuple
    err := NewFunc(nopos, nil, "Error", sig)                                  // 函数对象，函数名为 Error
    typ := &Named{underlying: NewInterfaceType([]*Func{err}, nil).Complete()} // 创建一个 defined type, 其 underlying type 是接口类型
    sig.recv = NewVar(nopos, nil, "", typ)                                    // 设置函数的 receiver, 使其成为上面接口的方法
    def(NewTypeName(nopos, nil, "error", typ))                                // 注册函数类型
}
```

&#x20;       上述代码相当于往 Universe 中注册了如下的接口类型：

```go
type error interface {
    Error() string
}
```

&#x20;       而这正是 go 中对 error 类型的要求：实现`Error() string`方法，所以 error 类型的接口并没有在任何地方进行显示地申明，而是在此处通过代码创建的。

* defPredeclaredConsts\
  &#x20;注册语言内置的常量，一共有三个：true, false, iota. 为每个常量创建一个`Const`类型的 Object 对象。
* defPredeclaredNil\
  注册`nil`, 其对应的是`Nil`类型的 Object 对象。
* defPredeclaredFuncs \
  注册内置函数，例如 append, new, panic 等，每个内置函数对应一个`Builtin`类型的 Object 对象。
* defPredeclaredComparable\
  与注册 error 类型相似，该方法注册了另一个隐式接口 comprable, 该接口是[泛型的预定义 constraint](https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md#comparable-types-in-constraints). 例如可以如下方式使用该接口：

```go
// 使用 comparable 来限定 T 的类型
func compare[T comparable](i, j T) bool {} 
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://gocompiler.shizhz.me/golang-bian-yi-qi-lei-xing-jian-cha/4.5.21-quan-ju-zuo-yong-yu.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
