为什么在我的代码中goroutine似乎自动冻结了循环变量

import (
    "fmt"
)


func Print(i int) {
    fmt.Println(i)
}

func PrintR(i *int) {
    fmt.Println(*i)
}


func main() {
    for i := 0; i < 10; i++ {
        go Print(i)   // Get: 1 9 2 3 4 5 7 6 8 0

        //go func() {
        //  Print(i)
        //}()  // Get: 10 10 7 10 4 10 7 10 10 10 10

        //go PrintR(&i)  // Get: 7 10 10 7 10 7 10 10 10 10
    }
    select {

    }
}

The 2nd, 3rd example got the expected output, but I have thought that the 1st case's output go Print(i) should be similar to the 2nd's since both of them do not use a new variable to freeze the current value of i. What cause the difference?

Go passes parameter by value. Your first example does actually create a new variable and copy the current index into it before launching the new goroutine, which is the same as your 3rd example.

In the first example, the value of i is evaluated at the time that statement is executed. You see the other behavior in the second example because the anonymous function creates a closure on i, so you get whatever value i has at the time Print is called.