简体   繁体   中英

Why Golang allows circular reference in global scope but not in function scope

As I'm writing DB migrations using gormigrate , I need to define a many-to-many relationship between two structs in a function scope. But in golang 1.19 or 1.18 the following won't compile

package main

import "fmt"

func main() {
    type Student struct {
        Courses []*Course
        // [Error] ./prog.go:7:14: undefined: Course
    }
    type Course struct {
        Students []*Student
    }
    fmt.Printf("This won't compile")
}

However moving the definitions outside of the function will just work

package main

import "fmt"

type Student struct {
    Courses []*Course
}
type Course struct {
    Students []*Student
}

func main() {
    fmt.Printf("This works")
}

Can try this yourself at https://go.dev/play/p/GI53hhlUTbk

Why is this the case? And how can I make it work in a function scope?

Is there a similar syntax to typedef in C++, so we can declare a struct first and then define it later?

Thanks!

Circular type references are possible in the package block , but not inside a function. The section on Declarations and Scopes in the specification says:

  1. The scope of an identifier denoting a constant, type, variable, or function (but not method) declared at top level (outside any function) is the package block.

  1. The scope of a type identifier declared inside a function begins at the identifier in the TypeSpec and ends at the end of the innermost containing block.

The scope of a type in a function starts at the type declaration. The scope of a type in the package block is the entire package.

There is not a way to declare the name of a type and later define the type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM