Compare commits
85 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20c8f5ef7c | ||
|
|
ce2bb794fa | ||
|
|
c4a297cbdc | ||
|
|
c473dceda8 | ||
|
|
f202764973 | ||
|
|
9d658604be | ||
|
|
166fff7072 | ||
|
|
8efc4f0735 | ||
|
|
6aa4f45c42 | ||
|
|
f3dbce93a4 | ||
|
|
0e3ea5732a | ||
|
|
1679870ea3 | ||
|
|
9b4ea62f69 | ||
|
|
eee72d1aae | ||
|
|
97cf8c4210 | ||
|
|
7bb8b4631f | ||
|
|
9f43170708 | ||
|
|
71112dbe87 | ||
|
|
4a8093609f | ||
|
|
7865c90737 | ||
|
|
e4e3d11772 | ||
|
|
a5242cbb9e | ||
|
|
c4d1bf5029 | ||
|
|
e003140c6e | ||
|
|
6b8c94e6c4 | ||
|
|
143e4a4559 | ||
|
|
dfeddbe823 | ||
|
|
021824930d | ||
|
|
b8301f10a8 | ||
|
|
2e8808317f | ||
|
|
79747f3d6f | ||
|
|
63825e7201 | ||
|
|
03ccda1a69 | ||
|
|
e02621577f | ||
|
|
ab869c8d20 | ||
|
|
b2aa636ea0 | ||
|
|
ae725fb3d9 | ||
|
|
14bc3b56b8 | ||
|
|
255b1cf1de | ||
|
|
d3fc5e990e | ||
|
|
dc082b5ded | ||
|
|
d9c402e20d | ||
|
|
09a1617640 | ||
|
|
cb642c44ba | ||
|
|
f76db27c77 | ||
|
|
996b1e33c8 | ||
|
|
236a0effaf | ||
|
|
eaeb445e17 | ||
|
|
6933ba2b4e | ||
|
|
a61a7d5bcd | ||
|
|
259f64cfd4 | ||
|
|
6c74ab7bec | ||
|
|
d64563edee | ||
|
|
07039262a0 | ||
|
|
4ed9ccb5c4 | ||
|
|
25edcfee7a | ||
|
|
d183f4205e | ||
|
|
821e9ee006 | ||
|
|
00e3f924c1 | ||
|
|
2248851d77 | ||
|
|
f74d1ea6d8 | ||
|
|
606b4c3a37 | ||
|
|
4e77fc9436 | ||
|
|
ad9db379e7 | ||
|
|
7be17d393f | ||
|
|
5665c9a410 | ||
|
|
1cf9d345aa | ||
|
|
f07f25f1ba | ||
|
|
c93b836c77 | ||
|
|
371103f0d1 | ||
|
|
8bd7afbe62 | ||
|
|
8ea3a493f4 | ||
|
|
f2abd346c0 | ||
|
|
c784713aca | ||
|
|
14acf618af | ||
|
|
fbee2baf9d | ||
|
|
2819b4167b | ||
|
|
2af660cb1f | ||
|
|
8323068414 | ||
|
|
5b62f9fdb6 | ||
|
|
4f66e3fe6c | ||
|
|
1335b4c64f | ||
|
|
da03c922ca | ||
|
|
9620116c30 | ||
|
|
dd7197f2a2 |
5
.github/workflows/go-cross.yml
vendored
5
.github/workflows/go-cross.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
|||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
go-version: [ 1.16, 1.17 ]
|
go-version: [ 1.19, '1.20' ]
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
|
|
||||||
include:
|
include:
|
||||||
@@ -34,6 +34,7 @@ jobs:
|
|||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v2
|
||||||
with:
|
with:
|
||||||
go-version: ${{ matrix.go-version }}
|
go-version: ${{ matrix.go-version }}
|
||||||
|
stable: true
|
||||||
|
|
||||||
# https://github.com/marketplace/actions/checkout
|
# https://github.com/marketplace/actions/checkout
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
@@ -43,7 +44,7 @@ jobs:
|
|||||||
|
|
||||||
# https://github.com/marketplace/actions/cache
|
# https://github.com/marketplace/actions/cache
|
||||||
- name: Cache Go modules
|
- name: Cache Go modules
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
# In order:
|
# In order:
|
||||||
# * Module download cache
|
# * Module download cache
|
||||||
|
|||||||
12
.github/workflows/main.yml
vendored
12
.github/workflows/main.yml
vendored
@@ -7,8 +7,8 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
GO_VERSION: 1.17
|
GO_VERSION: 1.19
|
||||||
GOLANGCI_LINT_VERSION: v1.42.1
|
GOLANGCI_LINT_VERSION: v1.47.1
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
@@ -45,12 +45,13 @@ jobs:
|
|||||||
needs: linting
|
needs: linting
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
go-version: [ 1.16, 1.17 ]
|
go-version: [ 1.19, '1.20' ]
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Go ${{ matrix.go-version }}
|
- name: Set up Go ${{ matrix.go-version }}
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v2
|
||||||
with:
|
with:
|
||||||
go-version: ${{ matrix.go-version }}
|
go-version: ${{ matrix.go-version }}
|
||||||
|
stable: true
|
||||||
|
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
@@ -75,13 +76,14 @@ jobs:
|
|||||||
working-directory: ${{ github.workspace }}/go/src/github.com/traefik/yaegi
|
working-directory: ${{ github.workspace }}/go/src/github.com/traefik/yaegi
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
go-version: [ 1.16, 1.17 ]
|
go-version: [ 1.19, '1.20' ]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Go ${{ matrix.go-version }}
|
- name: Set up Go ${{ matrix.go-version }}
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v2
|
||||||
with:
|
with:
|
||||||
go-version: ${{ matrix.go-version }}
|
go-version: ${{ matrix.go-version }}
|
||||||
|
stable: true
|
||||||
|
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
@@ -91,7 +93,7 @@ jobs:
|
|||||||
|
|
||||||
# https://github.com/marketplace/actions/cache
|
# https://github.com/marketplace/actions/cache
|
||||||
- name: Cache Go modules
|
- name: Cache Go modules
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ./_test/tmp
|
path: ./_test/tmp
|
||||||
key: ${{ runner.os }}-yaegi-${{ hashFiles('**//_test/tmp/') }}
|
key: ${{ runner.os }}-yaegi-${{ hashFiles('**//_test/tmp/') }}
|
||||||
|
|||||||
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@@ -6,7 +6,7 @@ on:
|
|||||||
- v[0-9]+.[0-9]+*
|
- v[0-9]+.[0-9]+*
|
||||||
|
|
||||||
env:
|
env:
|
||||||
GO_VERSION: 1.17
|
GO_VERSION: '1.20'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Cache Go modules
|
- name: Cache Go modules
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ~/go/pkg/mod
|
path: ~/go/pkg/mod
|
||||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
"scopelint", # deprecated
|
"scopelint", # deprecated
|
||||||
"interfacer", # deprecated
|
"interfacer", # deprecated
|
||||||
"maligned", # deprecated
|
"maligned", # deprecated
|
||||||
|
"exhaustivestruct", # deprecated
|
||||||
"lll",
|
"lll",
|
||||||
"gas",
|
"gas",
|
||||||
"dupl",
|
"dupl",
|
||||||
@@ -49,10 +50,15 @@
|
|||||||
"wrapcheck",
|
"wrapcheck",
|
||||||
"nestif",
|
"nestif",
|
||||||
"exhaustive",
|
"exhaustive",
|
||||||
"exhaustivestruct",
|
"exhaustruct",
|
||||||
"forbidigo",
|
"forbidigo",
|
||||||
"ifshort",
|
"ifshort",
|
||||||
"forcetypeassert",
|
"forcetypeassert",
|
||||||
|
"varnamelen",
|
||||||
|
"nosnakecase",
|
||||||
|
"nonamedreturns",
|
||||||
|
"nilnil",
|
||||||
|
"maintidx",
|
||||||
"errorlint", # TODO: must be reactivate before fixes
|
"errorlint", # TODO: must be reactivate before fixes
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -81,3 +87,6 @@
|
|||||||
[[issues.exclude-rules]]
|
[[issues.exclude-rules]]
|
||||||
path = "interp/interp_eval_test.go"
|
path = "interp/interp_eval_test.go"
|
||||||
linters = ["thelper"]
|
linters = ["thelper"]
|
||||||
|
[[issues.exclude-rules]]
|
||||||
|
path = "interp/debugger.go"
|
||||||
|
linters = ["containedctx"]
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ It powers executable Go scripts and plugins, in embedded interpreters or interac
|
|||||||
* Works everywhere Go works
|
* Works everywhere Go works
|
||||||
* All Go & runtime resources accessible from script (with control)
|
* All Go & runtime resources accessible from script (with control)
|
||||||
* Security: `unsafe` and `syscall` packages neither used nor exported by default
|
* Security: `unsafe` and `syscall` packages neither used nor exported by default
|
||||||
* Support Go 1.16 and Go 1.17 (the latest 2 major releases)
|
* Support Go 1.18 and Go 1.19 (the latest 2 major releases)
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
@@ -177,6 +177,8 @@ Beside the known [bugs] which are supposed to be fixed in the short term, there
|
|||||||
- Representation of types by `reflect` and printing values using %T may give different results between compiled mode and interpreted mode.
|
- Representation of types by `reflect` and printing values using %T may give different results between compiled mode and interpreted mode.
|
||||||
- Interpreting computation intensive code is likely to remain significantly slower than in compiled mode.
|
- Interpreting computation intensive code is likely to remain significantly slower than in compiled mode.
|
||||||
|
|
||||||
|
Go modules are not supported yet. Until that, it is necessary to install the source into `$GOPATH/src/github.com/traefik/yaegi` to pass all the tests.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
[Contributing guide](CONTRIBUTING.md).
|
[Contributing guide](CONTRIBUTING.md).
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
package alias3
|
|
||||||
|
|
||||||
type T struct {
|
|
||||||
A string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *T) Print() {
|
|
||||||
println(t.A)
|
|
||||||
}
|
|
||||||
@@ -5,8 +5,8 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Defined an interface of stringBuilder that compatible with
|
// Define an interface of stringBuilder that is compatible with
|
||||||
// strings.Builder(go 1.10) and bytes.Buffer(< go 1.10)
|
// strings.Builder(go 1.10) and bytes.Buffer(< go 1.10).
|
||||||
type stringBuilder interface {
|
type stringBuilder interface {
|
||||||
WriteRune(r rune) (n int, err error)
|
WriteRune(r rune) (n int, err error)
|
||||||
WriteString(s string) (int, error)
|
WriteString(s string) (int, error)
|
||||||
|
|||||||
16
_test/assert3.go
Normal file
16
_test/assert3.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "crypto/rsa"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var pKey interface{} = &rsa.PublicKey{}
|
||||||
|
|
||||||
|
if _, ok := pKey.(*rsa.PublicKey); ok {
|
||||||
|
println("ok")
|
||||||
|
} else {
|
||||||
|
println("nok")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// ok
|
||||||
21
_test/assign17.go
Normal file
21
_test/assign17.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
s := make([]map[string]string, 0)
|
||||||
|
m := make(map[string]string)
|
||||||
|
m["m1"] = "m1"
|
||||||
|
m["m2"] = "m2"
|
||||||
|
s = append(s, m)
|
||||||
|
tmpStr := "start"
|
||||||
|
println(tmpStr)
|
||||||
|
for _, v := range s {
|
||||||
|
tmpStr, ok := v["m1"]
|
||||||
|
println(tmpStr, ok)
|
||||||
|
}
|
||||||
|
println(tmpStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// start
|
||||||
|
// m1 true
|
||||||
|
// start
|
||||||
21
_test/assign18.go
Normal file
21
_test/assign18.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
s := make([]map[string]string, 0)
|
||||||
|
m := make(map[string]string)
|
||||||
|
m["m1"] = "m1"
|
||||||
|
m["m2"] = "m2"
|
||||||
|
s = append(s, m)
|
||||||
|
tmpStr := "start"
|
||||||
|
println(tmpStr)
|
||||||
|
for _, v := range s {
|
||||||
|
tmpStr, _ := v["m1"]
|
||||||
|
println(tmpStr)
|
||||||
|
}
|
||||||
|
println(tmpStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// start
|
||||||
|
// m1
|
||||||
|
// start
|
||||||
24
_test/break0.go
Normal file
24
_test/break0.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
n := 2
|
||||||
|
m := 2
|
||||||
|
foo := true
|
||||||
|
OuterLoop:
|
||||||
|
println("Boo")
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
println("I: ", i)
|
||||||
|
for j := 0; j < m; j++ {
|
||||||
|
switch foo {
|
||||||
|
case true:
|
||||||
|
println(foo)
|
||||||
|
break OuterLoop
|
||||||
|
case false:
|
||||||
|
println(foo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error:
|
||||||
|
// 15:5: invalid break label OuterLoop
|
||||||
24
_test/break1.go
Normal file
24
_test/break1.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
n := 2
|
||||||
|
m := 2
|
||||||
|
foo := true
|
||||||
|
OuterLoop:
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
println("I: ", i)
|
||||||
|
for j := 0; j < m; j++ {
|
||||||
|
switch foo {
|
||||||
|
case true:
|
||||||
|
println(foo)
|
||||||
|
break OuterLoop
|
||||||
|
case false:
|
||||||
|
println(foo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// I: 0
|
||||||
|
// true
|
||||||
25
_test/break2.go
Normal file
25
_test/break2.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
n := 2
|
||||||
|
m := 2
|
||||||
|
foo := true
|
||||||
|
OuterLoop:
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
println("I: ", i)
|
||||||
|
for j := 0; j < m; j++ {
|
||||||
|
switch foo {
|
||||||
|
case true:
|
||||||
|
println(foo)
|
||||||
|
break OuterLoop
|
||||||
|
case false:
|
||||||
|
println(foo)
|
||||||
|
continue OuterLoop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// I: 0
|
||||||
|
// true
|
||||||
27
_test/break3.go
Normal file
27
_test/break3.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
n := 2
|
||||||
|
m := 2
|
||||||
|
foo := true
|
||||||
|
goto OuterLoop
|
||||||
|
println("Boo")
|
||||||
|
OuterLoop:
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
println("I: ", i)
|
||||||
|
for j := 0; j < m; j++ {
|
||||||
|
switch foo {
|
||||||
|
case true:
|
||||||
|
println(foo)
|
||||||
|
break OuterLoop
|
||||||
|
case false:
|
||||||
|
println(foo)
|
||||||
|
goto OuterLoop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// I: 0
|
||||||
|
// true
|
||||||
@@ -2,7 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -13,7 +13,7 @@ func client(uri string) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -21,7 +21,7 @@ func client(uri string) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
@@ -13,7 +13,7 @@ func client(uri string) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
@@ -40,7 +40,7 @@ func client(uri string) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
@@ -40,7 +40,7 @@ func client(uri string) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
@@ -41,7 +41,7 @@ func client(uri string) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
56
_test/cli7.go
Normal file
56
_test/cli7.go
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
)
|
||||||
|
|
||||||
|
type T struct {
|
||||||
|
http.ResponseWriter
|
||||||
|
}
|
||||||
|
|
||||||
|
type mw1 struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
var obj = map[string]interface{}{}
|
||||||
|
|
||||||
|
func (m *mw1) ServeHTTP(rw http.ResponseWriter, rq *http.Request) {
|
||||||
|
t := &T{
|
||||||
|
ResponseWriter: rw,
|
||||||
|
}
|
||||||
|
x := t.Header()
|
||||||
|
i := obj["m1"].(*mw1)
|
||||||
|
fmt.Fprint(rw, "Welcome to my website!", x, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
m1 := &mw1{}
|
||||||
|
|
||||||
|
obj["m1"] = m1
|
||||||
|
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
mux.HandleFunc("/", m1.ServeHTTP)
|
||||||
|
|
||||||
|
server := httptest.NewServer(mux)
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
client(server.URL)
|
||||||
|
}
|
||||||
|
|
||||||
|
func client(uri string) {
|
||||||
|
resp, err := http.Get(uri)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
fmt.Println(string(body))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// Welcome to my website!map[] &{}
|
||||||
41
_test/cli8.go
Normal file
41
_test/cli8.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
)
|
||||||
|
|
||||||
|
type T struct {
|
||||||
|
name string
|
||||||
|
next http.Handler
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *T) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||||
|
println("in T.ServeHTTP")
|
||||||
|
if t.next != nil {
|
||||||
|
t.next.ServeHTTP(rw, req)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(name string, next http.Handler) (http.Handler, error) { return &T{name, next}, nil }
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
next := func(rw http.ResponseWriter, req *http.Request) {
|
||||||
|
println("in next")
|
||||||
|
}
|
||||||
|
|
||||||
|
t, err := New("test", http.HandlerFunc(next))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
recorder := httptest.NewRecorder()
|
||||||
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
||||||
|
t.ServeHTTP(recorder, req)
|
||||||
|
println(recorder.Result().Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// in T.ServeHTTP
|
||||||
|
// in next
|
||||||
|
// 200 OK
|
||||||
36
_test/closure13.go
Normal file
36
_test/closure13.go
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type monkey struct {
|
||||||
|
test func() int
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
input := []string{"1", "2", "3"}
|
||||||
|
|
||||||
|
var monkeys []*monkey
|
||||||
|
|
||||||
|
for _, v := range input {
|
||||||
|
kong := monkey{}
|
||||||
|
divisor, err := strconv.Atoi(v)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Print(divisor, " ")
|
||||||
|
kong.test = func() int {
|
||||||
|
return divisor
|
||||||
|
}
|
||||||
|
monkeys = append(monkeys, &kong)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, mk := range monkeys {
|
||||||
|
fmt.Print(mk.test(), " ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1 2 3 1 2 3
|
||||||
32
_test/closure14.go
Normal file
32
_test/closure14.go
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type monkey struct {
|
||||||
|
test func() int
|
||||||
|
}
|
||||||
|
|
||||||
|
func getk(k int) (int, error) { return k, nil }
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
input := []string{"1", "2", "3"}
|
||||||
|
|
||||||
|
var monkeys []*monkey
|
||||||
|
|
||||||
|
for k := range input {
|
||||||
|
kong := monkey{}
|
||||||
|
divisor, _ := getk(k)
|
||||||
|
fmt.Print(divisor, " ")
|
||||||
|
kong.test = func() int {
|
||||||
|
return divisor
|
||||||
|
}
|
||||||
|
monkeys = append(monkeys, &kong)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, mk := range monkeys {
|
||||||
|
fmt.Print(mk.test(), " ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 0 1 2 0 1 2
|
||||||
26
_test/cont2.go
Normal file
26
_test/cont2.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
n := 2
|
||||||
|
m := 2
|
||||||
|
foo := true
|
||||||
|
OuterLoop:
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
println("I: ", i)
|
||||||
|
for j := 0; j < m; j++ {
|
||||||
|
switch foo {
|
||||||
|
case true:
|
||||||
|
println(foo)
|
||||||
|
continue OuterLoop
|
||||||
|
case false:
|
||||||
|
println(foo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// I: 0
|
||||||
|
// true
|
||||||
|
// I: 1
|
||||||
|
// true
|
||||||
24
_test/cont3.go
Normal file
24
_test/cont3.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
n := 2
|
||||||
|
m := 2
|
||||||
|
foo := true
|
||||||
|
OuterLoop:
|
||||||
|
println("boo")
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
println("I: ", i)
|
||||||
|
for j := 0; j < m; j++ {
|
||||||
|
switch foo {
|
||||||
|
case true:
|
||||||
|
println(foo)
|
||||||
|
continue OuterLoop
|
||||||
|
case false:
|
||||||
|
println(foo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error:
|
||||||
|
// 15:5: invalid continue label OuterLoop
|
||||||
18
_test/convert3.go
Normal file
18
_test/convert3.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
next := func(rw http.ResponseWriter, req *http.Request) {
|
||||||
|
rw.Header().Set("Cache-Control", "max-age=20")
|
||||||
|
rw.WriteHeader(http.StatusOK)
|
||||||
|
}
|
||||||
|
f := http.HandlerFunc(next)
|
||||||
|
fmt.Printf("%T\n", f.ServeHTTP)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// func(http.ResponseWriter, *http.Request)
|
||||||
@@ -2,12 +2,11 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
file, err := ioutil.TempFile("", "yeagibench")
|
file, err := os.CreateTemp("", "yeagibench")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@@ -23,7 +22,7 @@ func main() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err := ioutil.ReadFile(file.Name())
|
b, err := os.ReadFile(file.Name())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|||||||
25
_test/fun28.go
Normal file
25
_test/fun28.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
type T struct {
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func finalize(t *T) { println("finalize") }
|
||||||
|
|
||||||
|
func newT() *T {
|
||||||
|
t := new(T)
|
||||||
|
runtime.SetFinalizer(t, finalize)
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
t := newT()
|
||||||
|
println(t != nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
39
_test/gen1.go
Normal file
39
_test/gen1.go
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// SumInts adds together the values of m.
|
||||||
|
func SumInts(m map[string]int64) int64 {
|
||||||
|
var s int64
|
||||||
|
for _, v := range m {
|
||||||
|
s += v
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// SumFloats adds together the values of m.
|
||||||
|
func SumFloats(m map[string]float64) float64 {
|
||||||
|
var s float64
|
||||||
|
for _, v := range m {
|
||||||
|
s += v
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Initialize a map for the integer values
|
||||||
|
ints := map[string]int64{
|
||||||
|
"first": 34,
|
||||||
|
"second": 12,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize a map for the float values
|
||||||
|
floats := map[string]float64{
|
||||||
|
"first": 35.98,
|
||||||
|
"second": 26.99,
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Non-Generic Sums: %v and %v\n",
|
||||||
|
SumInts(ints),
|
||||||
|
SumFloats(floats))
|
||||||
|
}
|
||||||
12
_test/gen10.go
Normal file
12
_test/gen10.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func genFunc() (f func()) {
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
println(genFunc() == nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
33
_test/gen11.go
Normal file
33
_test/gen11.go
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/netip"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Slice[T any] struct {
|
||||||
|
x []T
|
||||||
|
}
|
||||||
|
|
||||||
|
type IPPrefixSlice struct {
|
||||||
|
x Slice[netip.Prefix]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v Slice[T]) MarshalJSON() ([]byte, error) { return json.Marshal(v.x) }
|
||||||
|
|
||||||
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (v IPPrefixSlice) MarshalJSON() ([]byte, error) {
|
||||||
|
return v.x.MarshalJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
t := IPPrefixSlice{}
|
||||||
|
fmt.Println(t)
|
||||||
|
b, e := t.MarshalJSON()
|
||||||
|
fmt.Println(string(b), e)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// {{[]}}
|
||||||
|
// null <nil>
|
||||||
31
_test/gen12.go
Normal file
31
_test/gen12.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func MapOf[K comparable, V any](m map[K]V) Map[K, V] {
|
||||||
|
return Map[K, V]{m}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Map[K comparable, V any] struct {
|
||||||
|
ж map[K]V
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v MapView) Int() Map[string, int] { return MapOf(v.ж.Int) }
|
||||||
|
|
||||||
|
type VMap struct {
|
||||||
|
Int map[string]int
|
||||||
|
}
|
||||||
|
|
||||||
|
type MapView struct {
|
||||||
|
ж *VMap
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
mv := MapView{&VMap{}}
|
||||||
|
fmt.Println(mv.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// &{map[]}
|
||||||
18
_test/gen13.go
Normal file
18
_test/gen13.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type Map[K comparable, V any] struct {
|
||||||
|
ж map[K]V
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Map[K, V]) Has(k K) bool {
|
||||||
|
_, ok := m.ж[k]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
m := Map[string, float64]{}
|
||||||
|
println(m.Has("test"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// false
|
||||||
34
_test/gen2.go
Normal file
34
_test/gen2.go
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// SumIntsOrFloats sums the values of map m. It supports both int64 and float64
|
||||||
|
// as types for map values.
|
||||||
|
func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V {
|
||||||
|
var s V
|
||||||
|
for _, v := range m {
|
||||||
|
s += v
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Initialize a map for the integer values
|
||||||
|
ints := map[string]int64{
|
||||||
|
"first": 34,
|
||||||
|
"second": 12,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize a map for the float values
|
||||||
|
floats := map[string]float64{
|
||||||
|
"first": 35.98,
|
||||||
|
"second": 26.99,
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Generic Sums: %v and %v\n",
|
||||||
|
SumIntsOrFloats[string, int64](ints),
|
||||||
|
SumIntsOrFloats[string, float64](floats))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// Generic Sums: 46 and 62.97
|
||||||
22
_test/gen3.go
Normal file
22
_test/gen3.go
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type Number interface {
|
||||||
|
int | int64 | ~float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func Sum[T Number](numbers []T) T {
|
||||||
|
var total T
|
||||||
|
for _, x := range numbers {
|
||||||
|
total += x
|
||||||
|
}
|
||||||
|
return total
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
xs := []int{3, 5, 10}
|
||||||
|
total := Sum(xs)
|
||||||
|
println(total)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 18
|
||||||
42
_test/gen4.go
Normal file
42
_test/gen4.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type List[T any] struct {
|
||||||
|
head, tail *element[T]
|
||||||
|
}
|
||||||
|
|
||||||
|
// A recursive generic type.
|
||||||
|
type element[T any] struct {
|
||||||
|
next *element[T]
|
||||||
|
val T
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lst *List[T]) Push(v T) {
|
||||||
|
if lst.tail == nil {
|
||||||
|
lst.head = &element[T]{val: v}
|
||||||
|
lst.tail = lst.head
|
||||||
|
} else {
|
||||||
|
lst.tail.next = &element[T]{val: v}
|
||||||
|
lst.tail = lst.tail.next
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lst *List[T]) GetAll() []T {
|
||||||
|
var elems []T
|
||||||
|
for e := lst.head; e != nil; e = e.next {
|
||||||
|
elems = append(elems, e.val)
|
||||||
|
}
|
||||||
|
return elems
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
lst := List[int]{}
|
||||||
|
lst.Push(10)
|
||||||
|
lst.Push(13)
|
||||||
|
lst.Push(23)
|
||||||
|
fmt.Println("list:", lst.GetAll())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// list: [10 13 23]
|
||||||
24
_test/gen5.go
Normal file
24
_test/gen5.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type Set[Elem comparable] struct {
|
||||||
|
m map[Elem]struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Make[Elem comparable]() Set[Elem] {
|
||||||
|
return Set[Elem]{m: make(map[Elem]struct{})}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Set[Elem]) Add(v Elem) {
|
||||||
|
s.m[v] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
s := Make[int]()
|
||||||
|
s.Add(1)
|
||||||
|
fmt.Println(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// {map[1:{}]}
|
||||||
19
_test/gen6.go
Normal file
19
_test/gen6.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func MapKeys[K comparable, V any](m map[K]V) []K {
|
||||||
|
r := make([]K, 0, len(m))
|
||||||
|
for k := range m {
|
||||||
|
r = append(r, k)
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var m = map[int]string{1: "2", 2: "4", 4: "8"}
|
||||||
|
|
||||||
|
// Test type inference
|
||||||
|
println(len(MapKeys(m)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 3
|
||||||
19
_test/gen7.go
Normal file
19
_test/gen7.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func MapKeys[K comparable, V any](m map[K]V) []K {
|
||||||
|
r := make([]K, 0, len(m))
|
||||||
|
for k := range m {
|
||||||
|
r = append(r, k)
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var m = map[int]string{1: "2", 2: "4", 4: "8"}
|
||||||
|
|
||||||
|
// Test type inference
|
||||||
|
println(len(MapKeys))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error:
|
||||||
|
// invalid argument for len
|
||||||
15
_test/gen8.go
Normal file
15
_test/gen8.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type Float interface {
|
||||||
|
~float32 | ~float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func add[T Float](a, b T) float64 { return float64(a) + float64(b) }
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var x, y int = 1, 2
|
||||||
|
println(add(x, y))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error:
|
||||||
|
// int does not implement main.Float
|
||||||
14
_test/gen9.go
Normal file
14
_test/gen9.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type Float interface {
|
||||||
|
~float32 | ~float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func add[T Float](a, b T) float64 { return float64(a) + float64(b) }
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
println(add(1, 2))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error:
|
||||||
|
// untyped int does not implement main.Float
|
||||||
@@ -2,7 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
func main() {
|
func main() {
|
||||||
r := strings.NewReader("Go is a general-purpose language designed with systems programming in mind.")
|
r := strings.NewReader("Go is a general-purpose language designed with systems programming in mind.")
|
||||||
|
|
||||||
b, err := ioutil.ReadAll(r)
|
b, err := io.ReadAll(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -13,7 +12,7 @@ type sink interface {
|
|||||||
|
|
||||||
func newSink() sink {
|
func newSink() sink {
|
||||||
// return os.Stdout // Stdout is special in yaegi tests
|
// return os.Stdout // Stdout is special in yaegi tests
|
||||||
file, err := ioutil.TempFile("", "yaegi-test.*")
|
file, err := os.CreateTemp("", "yaegi-test.*")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -37,7 +36,7 @@ func (s *Sink2) Close() error { println("in Close", s.name); retu
|
|||||||
func newS2(name string) Sink { return Sink1{name} }
|
func newS2(name string) Sink { return Sink1{name} }
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
tmpfile, err := ioutil.TempFile("", "xxx")
|
tmpfile, err := os.CreateTemp("", "xxx")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|||||||
19
_test/issue-1311.go
Normal file
19
_test/issue-1311.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type T struct {
|
||||||
|
v interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func f() (ret int64, err error) {
|
||||||
|
ret += 2
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
t := &T{}
|
||||||
|
t.v, _ = f()
|
||||||
|
println(t.v.(int64))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2
|
||||||
32
_test/issue-1315.go
Normal file
32
_test/issue-1315.go
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type Intf interface {
|
||||||
|
M()
|
||||||
|
}
|
||||||
|
|
||||||
|
type T struct {
|
||||||
|
s string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *T) M() { println("in M") }
|
||||||
|
|
||||||
|
func f(i interface{}) {
|
||||||
|
switch j := i.(type) {
|
||||||
|
case Intf:
|
||||||
|
j.M()
|
||||||
|
default:
|
||||||
|
println("default")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var i Intf
|
||||||
|
var k interface{} = 1
|
||||||
|
i = &T{"hello"}
|
||||||
|
f(i)
|
||||||
|
f(k)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// in M
|
||||||
|
// default
|
||||||
29
_test/issue-1320.go
Normal file
29
_test/issue-1320.go
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type Pooler interface {
|
||||||
|
Get() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type baseClient struct {
|
||||||
|
connPool Pooler
|
||||||
|
}
|
||||||
|
|
||||||
|
type connPool struct {
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *connPool) Get() string { return c.name }
|
||||||
|
|
||||||
|
func newBaseClient(i int, p Pooler) *baseClient {
|
||||||
|
return &baseClient{connPool: p}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newConnPool() *connPool { return &connPool{name: "connPool"} }
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
b := newBaseClient(0, newConnPool())
|
||||||
|
println(b.connPool.(*connPool).name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// connPool
|
||||||
42
_test/issue-1326.go
Normal file
42
_test/issue-1326.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type Option interface {
|
||||||
|
apply(*T)
|
||||||
|
}
|
||||||
|
|
||||||
|
type T struct {
|
||||||
|
s string
|
||||||
|
}
|
||||||
|
|
||||||
|
type opt struct {
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *opt) apply(t *T) {
|
||||||
|
println(o.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func BuildOptions() []Option {
|
||||||
|
return []Option{
|
||||||
|
&opt{"opt1"},
|
||||||
|
&opt{"opt2"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewT(name string, options ...Option) *T {
|
||||||
|
t := &T{name}
|
||||||
|
for _, opt := range options {
|
||||||
|
opt.apply(t)
|
||||||
|
}
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
t := NewT("hello", BuildOptions()...)
|
||||||
|
println(t.s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// opt1
|
||||||
|
// opt2
|
||||||
|
// hello
|
||||||
16
_test/issue-1328.go
Normal file
16
_test/issue-1328.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha1"
|
||||||
|
"encoding/hex"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
script := "hello"
|
||||||
|
sumRaw := sha1.Sum([]byte(script))
|
||||||
|
sum := hex.EncodeToString(sumRaw[:])
|
||||||
|
println(sum)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
|
||||||
42
_test/issue-1330.go
Normal file
42
_test/issue-1330.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
type wrappedConn struct {
|
||||||
|
net.Conn
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
_, err := net.Listen("tcp", "127.0.0.1:49153")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dialer := &net.Dialer{
|
||||||
|
LocalAddr: &net.TCPAddr{
|
||||||
|
IP: net.ParseIP("127.0.0.1"),
|
||||||
|
Port: 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
conn, err := dialer.Dial("tcp", "127.0.0.1:49153")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
t := &wrappedConn{conn}
|
||||||
|
var w io.Writer = t
|
||||||
|
if n, err := w.Write([]byte("hello")); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
} else {
|
||||||
|
fmt.Println(n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 5
|
||||||
17
_test/issue-1332.go
Normal file
17
_test/issue-1332.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func run(fn func(name string)) { fn("test") }
|
||||||
|
|
||||||
|
type T2 struct {
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *T2) f(s string) { println(s, t.name) }
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
t2 := &T2{"foo"}
|
||||||
|
run(t2.f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// test foo
|
||||||
37
_test/issue-1333.go
Normal file
37
_test/issue-1333.go
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func mock(name string) http.HandlerFunc {
|
||||||
|
return func(rw http.ResponseWriter, req *http.Request) {
|
||||||
|
fmt.Fprint(rw, "Hello ", name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func client(uri string) {
|
||||||
|
resp, err := http.Get(uri)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println(string(body))
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
server := httptest.NewServer(mux)
|
||||||
|
defer server.Close()
|
||||||
|
mux.Handle("/", mock("foo"))
|
||||||
|
client(server.URL)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// Hello foo
|
||||||
26
_test/issue-1337.go
Normal file
26
_test/issue-1337.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func f(i interface{}) {
|
||||||
|
switch at := i.(type) {
|
||||||
|
case int, int8:
|
||||||
|
println("integer", at)
|
||||||
|
case io.Reader:
|
||||||
|
println("reader")
|
||||||
|
}
|
||||||
|
println("bye")
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var fd *os.File
|
||||||
|
var r io.Reader = fd
|
||||||
|
f(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// reader
|
||||||
|
// bye
|
||||||
12
_test/issue-1342.go
Normal file
12
_test/issue-1342.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var a interface{}
|
||||||
|
a = "a"
|
||||||
|
fmt.Println(a, a == "a")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// a true
|
||||||
13
_test/issue-1344.go
Normal file
13
_test/issue-1344.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var m = map[string]interface{}{"a": "a"}
|
||||||
|
a, _ := m["a"]
|
||||||
|
b, ok := a.(string)
|
||||||
|
fmt.Println("a:", a, ", b:", b, ", ok:", ok)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// a: a , b: a , ok: true
|
||||||
21
_test/issue-1354.go
Normal file
21
_test/issue-1354.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
println(test()) // Go prints true, Yaegi false
|
||||||
|
}
|
||||||
|
|
||||||
|
func test() bool {
|
||||||
|
if true {
|
||||||
|
goto label
|
||||||
|
}
|
||||||
|
goto label
|
||||||
|
label:
|
||||||
|
println("Go continues here")
|
||||||
|
return true
|
||||||
|
println("Yaegi goes straight to this return (this line is never printed)")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// Go continues here
|
||||||
|
// true
|
||||||
22
_test/issue-1355.go
Normal file
22
_test/issue-1355.go
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/traefik/yaegi/_test/p2"
|
||||||
|
|
||||||
|
func f(i interface{}) {
|
||||||
|
_, ok := i.(p2.I)
|
||||||
|
println("ok:", ok)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var v *p2.T
|
||||||
|
var i interface{}
|
||||||
|
|
||||||
|
i = v
|
||||||
|
_, ok := i.(p2.I)
|
||||||
|
println("ok:", ok)
|
||||||
|
f(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// ok: true
|
||||||
|
// ok: true
|
||||||
14
_test/issue-1360.go
Normal file
14
_test/issue-1360.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
. "net"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
v := IP{}
|
||||||
|
fmt.Println(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// <nil>
|
||||||
27
_test/issue-1361.go
Normal file
27
_test/issue-1361.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
)
|
||||||
|
|
||||||
|
type obj struct {
|
||||||
|
num float64
|
||||||
|
}
|
||||||
|
|
||||||
|
type Fun func(o *obj) (r *obj, err error)
|
||||||
|
|
||||||
|
func numFun(fn func(f float64) float64) Fun {
|
||||||
|
return func(o *obj) (*obj, error) {
|
||||||
|
return &obj{fn(o.num)}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
f := numFun(math.Cos)
|
||||||
|
r, err := f(&obj{})
|
||||||
|
fmt.Println(r, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// &{1} <nil>
|
||||||
16
_test/issue-1364.go
Normal file
16
_test/issue-1364.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var value interface{}
|
||||||
|
var err error
|
||||||
|
value, err = strconv.ParseFloat("123", 64)
|
||||||
|
fmt.Println(value, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 123 <nil>
|
||||||
18
_test/issue-1365.go
Normal file
18
_test/issue-1365.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func genInt() (int, error) { return 3, nil }
|
||||||
|
|
||||||
|
func getInt() (value int) {
|
||||||
|
value, err := genInt()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
println(getInt())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 3
|
||||||
16
_test/issue-1368.go
Normal file
16
_test/issue-1368.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
const dollar byte = 36
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var c byte = 36
|
||||||
|
switch true {
|
||||||
|
case c == dollar:
|
||||||
|
println("ok")
|
||||||
|
default:
|
||||||
|
println("not ok")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// ok
|
||||||
18
_test/issue-1371.go
Normal file
18
_test/issue-1371.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type node struct {
|
||||||
|
parent *node
|
||||||
|
child []*node
|
||||||
|
key string
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
root := &node{key: "root"}
|
||||||
|
root.child = nil
|
||||||
|
fmt.Println("root:", root)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// root: &{<nil> [] root}
|
||||||
17
_test/issue-1373.go
Normal file
17
_test/issue-1373.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"go/ast"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewBadExpr() ast.Expr {
|
||||||
|
return &ast.BadExpr{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Printf("%T\n", NewBadExpr().(*ast.BadExpr))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// *ast.BadExpr
|
||||||
38
_test/issue-1375.go
Normal file
38
_test/issue-1375.go
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type Option func(*Struct)
|
||||||
|
|
||||||
|
func WithOption(opt string) Option {
|
||||||
|
return func(s *Struct) {
|
||||||
|
s.opt = opt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Struct struct {
|
||||||
|
opt string
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(opts ...Option) *Struct {
|
||||||
|
s := new(Struct)
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt(s)
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Struct) ShowOption() {
|
||||||
|
fmt.Println(s.opt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
opts := []Option{
|
||||||
|
WithOption("test"),
|
||||||
|
}
|
||||||
|
s := New(opts...)
|
||||||
|
s.ShowOption()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// test
|
||||||
21
_test/issue-1378.go
Normal file
21
_test/issue-1378.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
t, err := time.Parse(time.RFC3339, "2006-01-02T15:04:05Z")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fn := func() error {
|
||||||
|
_, err := t.GobEncode()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println(fn())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// <nil>
|
||||||
58
_test/issue-1381.go
Normal file
58
_test/issue-1381.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var bufPtrOne *bytes.Buffer
|
||||||
|
var bufPtrTwo *bytes.Buffer
|
||||||
|
var bufPtrThree *bytes.Buffer
|
||||||
|
var bufPtrFour *bytes.Buffer
|
||||||
|
|
||||||
|
for i := 0; i < 2; i++ {
|
||||||
|
bufOne := bytes.Buffer{}
|
||||||
|
bufTwo := &bytes.Buffer{}
|
||||||
|
var bufThree bytes.Buffer
|
||||||
|
bufFour := new(bytes.Buffer)
|
||||||
|
|
||||||
|
if bufPtrOne == nil {
|
||||||
|
bufPtrOne = &bufOne
|
||||||
|
} else if bufPtrOne == &bufOne {
|
||||||
|
fmt.Println("bufOne was not properly redeclared")
|
||||||
|
} else {
|
||||||
|
fmt.Println("bufOne is properly redeclared")
|
||||||
|
}
|
||||||
|
|
||||||
|
if bufPtrTwo == nil {
|
||||||
|
bufPtrTwo = bufTwo
|
||||||
|
} else if bufPtrTwo == bufTwo {
|
||||||
|
fmt.Println("bufTwo was not properly redeclared")
|
||||||
|
} else {
|
||||||
|
fmt.Println("bufTwo is properly redeclared")
|
||||||
|
}
|
||||||
|
|
||||||
|
if bufPtrThree == nil {
|
||||||
|
bufPtrThree = &bufThree
|
||||||
|
} else if bufPtrThree == &bufThree {
|
||||||
|
fmt.Println("bufThree was not properly redeclared")
|
||||||
|
} else {
|
||||||
|
fmt.Println("bufThree is properly redeclared")
|
||||||
|
}
|
||||||
|
|
||||||
|
if bufPtrFour == nil {
|
||||||
|
bufPtrFour = bufFour
|
||||||
|
} else if bufPtrFour == bufFour {
|
||||||
|
fmt.Println("bufFour was not properly redeclared")
|
||||||
|
} else {
|
||||||
|
fmt.Println("bufFour is properly redeclared")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// bufOne is properly redeclared
|
||||||
|
// bufTwo is properly redeclared
|
||||||
|
// bufThree is properly redeclared
|
||||||
|
// bufFour is properly redeclared
|
||||||
22
_test/issue-1404.go
Normal file
22
_test/issue-1404.go
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type I interface {
|
||||||
|
inI()
|
||||||
|
}
|
||||||
|
|
||||||
|
type T struct {
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *T) inI() {}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var i I = &T{name: "foo"}
|
||||||
|
|
||||||
|
if i, ok := i.(*T); ok {
|
||||||
|
println(i.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// foo
|
||||||
16
_test/issue-1408.go
Normal file
16
_test/issue-1408.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type (
|
||||||
|
Number = int32
|
||||||
|
Number2 = Number
|
||||||
|
)
|
||||||
|
|
||||||
|
func f(n Number2) { println(n) }
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var n Number = 5
|
||||||
|
f(n)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 5
|
||||||
16
_test/issue-1411.go
Normal file
16
_test/issue-1411.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type Number int32
|
||||||
|
|
||||||
|
func (n Number) IsValid() bool { return true }
|
||||||
|
|
||||||
|
type Number1 = Number
|
||||||
|
|
||||||
|
type Number2 = Number1
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
a := Number2(5)
|
||||||
|
println(a.IsValid())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output: true
|
||||||
17
_test/issue-1416.go
Normal file
17
_test/issue-1416.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type Number int32
|
||||||
|
|
||||||
|
type Number1 = Number
|
||||||
|
|
||||||
|
type Number2 = Number1
|
||||||
|
|
||||||
|
func (n Number2) IsValid() bool { return true }
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
a := Number(5)
|
||||||
|
println(a.IsValid())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
9
_test/issue-1421.go
Normal file
9
_test/issue-1421.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type Number = int
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
println(Number(1) < int(2))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output: true
|
||||||
44
_test/issue-1425.go
Normal file
44
_test/issue-1425.go
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WrappedReader struct {
|
||||||
|
reader io.Reader
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wr WrappedReader) Read(p []byte) (n int, err error) {
|
||||||
|
return wr.reader.Read(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Of course, this implementation is completely stupid because it does not write
|
||||||
|
// to the intended writer, as any honest WriteTo implementation should. its
|
||||||
|
// implemtion is just to make obvious the divergence of behaviour with yaegi.
|
||||||
|
func (wr WrappedReader) WriteTo(w io.Writer) (n int64, err error) {
|
||||||
|
// Ignore w, send to Stdout to prove whether this WriteTo is used.
|
||||||
|
data, err := io.ReadAll(wr)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
nn, err := os.Stdout.Write(data)
|
||||||
|
return int64(nn), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
f := strings.NewReader("hello world")
|
||||||
|
wr := WrappedReader{reader: f}
|
||||||
|
|
||||||
|
// behind the scenes, io.Copy is supposed to use wr.WriteTo if the implementation exists.
|
||||||
|
// With Go, it works as expected, i.e. the output is sent to os.Stdout.
|
||||||
|
// With Yaegi, it doesn't, i.e. the output is sent to io.Discard.
|
||||||
|
if _, err := io.Copy(io.Discard, wr); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// hello world
|
||||||
25
_test/issue-1439.go
Normal file
25
_test/issue-1439.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type Transformer interface {
|
||||||
|
Reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
type Encoder struct {
|
||||||
|
Transformer
|
||||||
|
}
|
||||||
|
|
||||||
|
type nop struct{}
|
||||||
|
|
||||||
|
func (nop) Reset() { println("Reset") }
|
||||||
|
|
||||||
|
func f(e Transformer) {
|
||||||
|
e.Reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
e := Encoder{Transformer: nop{}}
|
||||||
|
f(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// Reset
|
||||||
41
_test/issue-1442.go
Normal file
41
_test/issue-1442.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ctx, _ := context.WithCancel(context.Background())
|
||||||
|
ch := make(chan string, 20)
|
||||||
|
defer close(ch)
|
||||||
|
|
||||||
|
go func(ctx context.Context, ch <-chan string) {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
case tmp := <-ch:
|
||||||
|
_ = tmp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}(ctx, ch)
|
||||||
|
|
||||||
|
for _, i := range "abcdef" {
|
||||||
|
for _, j := range "0123456789" {
|
||||||
|
// i, j := "a", "0"
|
||||||
|
for _, k := range "ABCDEF" {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
tmp := string(i) + string(j) + string(k)
|
||||||
|
ch <- tmp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
//
|
||||||
20
_test/issue-1447.go
Normal file
20
_test/issue-1447.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type I interface {
|
||||||
|
Name() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type S struct {
|
||||||
|
iMap map[string]I
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
s := S{}
|
||||||
|
s.iMap = map[string]I{}
|
||||||
|
fmt.Println(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// {map[]}
|
||||||
19
_test/issue-1451.go
Normal file
19
_test/issue-1451.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type t1 uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
n1 t1 = iota
|
||||||
|
n2
|
||||||
|
)
|
||||||
|
|
||||||
|
type T struct {
|
||||||
|
elem [n2 + 1]int
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
println(len(T{}.elem))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 2
|
||||||
22
_test/issue-1454.go
Normal file
22
_test/issue-1454.go
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type I2 interface {
|
||||||
|
I2() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type I interface {
|
||||||
|
I2
|
||||||
|
}
|
||||||
|
|
||||||
|
type S struct{}
|
||||||
|
|
||||||
|
func (*S) I2() string { return "foo" }
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var i I
|
||||||
|
_, ok := i.(*S)
|
||||||
|
println(ok)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// false
|
||||||
22
_test/issue-1459.go
Normal file
22
_test/issue-1459.go
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type funclistItem func()
|
||||||
|
|
||||||
|
type funclist struct {
|
||||||
|
list []funclistItem
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
funcs := funclist{}
|
||||||
|
|
||||||
|
funcs.list = append(funcs.list, func() { fmt.Println("first") })
|
||||||
|
|
||||||
|
for _, f := range funcs.list {
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// first
|
||||||
84
_test/issue-1460.go
Normal file
84
_test/issue-1460.go
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"net/netip"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
func unmarshalJSON[T any](b []byte, x *[]T) error {
|
||||||
|
if *x != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
if len(b) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return json.Unmarshal(b, x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SliceOfViews[T ViewCloner[T, V], V StructView[T]](x []T) SliceView[T, V] {
|
||||||
|
return SliceView[T, V]{x}
|
||||||
|
}
|
||||||
|
|
||||||
|
type StructView[T any] interface {
|
||||||
|
Valid() bool
|
||||||
|
AsStruct() T
|
||||||
|
}
|
||||||
|
|
||||||
|
type SliceView[T ViewCloner[T, V], V StructView[T]] struct {
|
||||||
|
ж []T
|
||||||
|
}
|
||||||
|
|
||||||
|
type ViewCloner[T any, V StructView[T]] interface {
|
||||||
|
View() V
|
||||||
|
Clone() T
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v SliceView[T, V]) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
||||||
|
|
||||||
|
func (v *SliceView[T, V]) UnmarshalJSON(b []byte) error { return unmarshalJSON(b, &v.ж) }
|
||||||
|
|
||||||
|
type Slice[T any] struct {
|
||||||
|
ж []T
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v Slice[T]) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
||||||
|
|
||||||
|
func (v *Slice[T]) UnmarshalJSON(b []byte) error { return unmarshalJSON(b, &v.ж) }
|
||||||
|
|
||||||
|
func SliceOf[T any](x []T) Slice[T] {
|
||||||
|
return Slice[T]{x}
|
||||||
|
}
|
||||||
|
|
||||||
|
type IPPrefixSlice struct {
|
||||||
|
ж Slice[netip.Prefix]
|
||||||
|
}
|
||||||
|
|
||||||
|
type viewStruct struct {
|
||||||
|
Int int
|
||||||
|
Strings Slice[string]
|
||||||
|
StringsPtr *Slice[string] `json:",omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ss := SliceOf([]string{"bar"})
|
||||||
|
in := viewStruct{
|
||||||
|
Int: 1234,
|
||||||
|
Strings: ss,
|
||||||
|
StringsPtr: &ss,
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
encoder := json.NewEncoder(&buf)
|
||||||
|
encoder.SetIndent("", "")
|
||||||
|
err1 := encoder.Encode(&in)
|
||||||
|
b := buf.Bytes()
|
||||||
|
var got viewStruct
|
||||||
|
err2 := json.Unmarshal(b, &got)
|
||||||
|
println(err1 == nil, err2 == nil, reflect.DeepEqual(got, in))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true true true
|
||||||
24
_test/issue-1465.go
Normal file
24
_test/issue-1465.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SomeFunc[T int | string](defaultValue T) T {
|
||||||
|
switch v := any(&defaultValue).(type) {
|
||||||
|
case *string:
|
||||||
|
*v = *v + " abc"
|
||||||
|
case *int:
|
||||||
|
*v -= 234
|
||||||
|
}
|
||||||
|
return defaultValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println(SomeFunc("test"))
|
||||||
|
fmt.Println(SomeFunc(1234))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// test abc
|
||||||
|
// 1000
|
||||||
24
_test/issue-1466.go
Normal file
24
_test/issue-1466.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SomeFunc(defaultValue interface{}) interface{} {
|
||||||
|
switch v := defaultValue.(type) {
|
||||||
|
case string:
|
||||||
|
return v + " abc"
|
||||||
|
case int:
|
||||||
|
return v - 234
|
||||||
|
}
|
||||||
|
panic("whoops")
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println(SomeFunc(1234))
|
||||||
|
fmt.Println(SomeFunc("test"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 1000
|
||||||
|
// test abc
|
||||||
15
_test/issue-1470.go
Normal file
15
_test/issue-1470.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type T struct {
|
||||||
|
num [tnum + 2]int
|
||||||
|
}
|
||||||
|
|
||||||
|
const tnum = 23
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
t := T{}
|
||||||
|
println(len(t.num))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 25
|
||||||
12
_test/issue-1475.go
Normal file
12
_test/issue-1475.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type T uint16
|
||||||
|
|
||||||
|
func f() T { return 0 }
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
println(f())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 0
|
||||||
23
_test/issue-1488.go
Normal file
23
_test/issue-1488.go
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type vector interface {
|
||||||
|
[]int | [3]int
|
||||||
|
}
|
||||||
|
|
||||||
|
func sum[V vector](v V) (out int) {
|
||||||
|
for i := 0; i < len(v); i++ {
|
||||||
|
out += v[i]
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
va := [3]int{1, 2, 3}
|
||||||
|
vs := []int{1, 2, 3}
|
||||||
|
fmt.Println(sum[[3]int](va), sum[[]int](vs))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 6 6
|
||||||
16
_test/issue-1496.go
Normal file
16
_test/issue-1496.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
a := []byte{} == nil
|
||||||
|
b := nil == []byte{}
|
||||||
|
c := nil == &struct{}{}
|
||||||
|
i := 100
|
||||||
|
d := nil == &i
|
||||||
|
var v interface{}
|
||||||
|
f := nil == v
|
||||||
|
g := v == nil
|
||||||
|
println(a, b, c, d, f, g)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// false false false false true true
|
||||||
43
_test/issue-1515.go
Normal file
43
_test/issue-1515.go
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type I1 interface {
|
||||||
|
I2
|
||||||
|
Wrap() *S3
|
||||||
|
}
|
||||||
|
|
||||||
|
type I2 interface {
|
||||||
|
F()
|
||||||
|
}
|
||||||
|
|
||||||
|
type S2 struct {
|
||||||
|
I2
|
||||||
|
}
|
||||||
|
|
||||||
|
func newS2(i2 I2) I1 {
|
||||||
|
return &S2{i2}
|
||||||
|
}
|
||||||
|
|
||||||
|
type S3 struct {
|
||||||
|
base *S2
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *S2) Wrap() *S3 {
|
||||||
|
i2 := s
|
||||||
|
return &S3{i2}
|
||||||
|
}
|
||||||
|
|
||||||
|
type T struct {
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *T) F() { println("in F", t.name) }
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
t := &T{"test"}
|
||||||
|
s2 := newS2(t)
|
||||||
|
s3 := s2.Wrap()
|
||||||
|
s3.base.F()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// in F test
|
||||||
25
_test/issue-435.go
Normal file
25
_test/issue-435.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Foo int
|
||||||
|
|
||||||
|
func (f Foo) String() string {
|
||||||
|
return "foo-" + strconv.Itoa(int(f))
|
||||||
|
}
|
||||||
|
|
||||||
|
func print1(arg interface{}) {
|
||||||
|
fmt.Println(arg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var arg Foo = 3
|
||||||
|
var f = print1
|
||||||
|
f(arg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// foo-3
|
||||||
@@ -3,7 +3,6 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@@ -36,7 +35,7 @@ type pipe struct {
|
|||||||
|
|
||||||
func newReadAutoCloser(r io.Reader) readAutoCloser {
|
func newReadAutoCloser(r io.Reader) readAutoCloser {
|
||||||
if _, ok := r.(io.Closer); !ok {
|
if _, ok := r.(io.Closer); !ok {
|
||||||
return readAutoCloser{ioutil.NopCloser(r)}
|
return readAutoCloser{io.NopCloser(r)}
|
||||||
}
|
}
|
||||||
return readAutoCloser{r.(io.ReadCloser)}
|
return readAutoCloser{r.(io.ReadCloser)}
|
||||||
}
|
}
|
||||||
@@ -44,7 +43,7 @@ func newReadAutoCloser(r io.Reader) readAutoCloser {
|
|||||||
func main() {
|
func main() {
|
||||||
p := &pipe{}
|
p := &pipe{}
|
||||||
p.Reader = newReadAutoCloser(strings.NewReader("test"))
|
p.Reader = newReadAutoCloser(strings.NewReader("test"))
|
||||||
b, err := ioutil.ReadAll(p.Reader)
|
b, err := io.ReadAll(p.Reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "github.com/traefik/yaegi/_test/alias3"
|
import "github.com/traefik/yaegi/_test/named3"
|
||||||
|
|
||||||
var globalT *T
|
var globalT *T
|
||||||
|
|
||||||
@@ -8,10 +8,10 @@ func init() {
|
|||||||
globalT = &T{A: "test"}
|
globalT = &T{A: "test"}
|
||||||
}
|
}
|
||||||
|
|
||||||
type T alias3.T
|
type T named3.T
|
||||||
|
|
||||||
func (t *T) PrintT() {
|
func (t *T) PrintT() {
|
||||||
(*alias3.T)(t).Print()
|
(*named3.T)(t).Print()
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
31
_test/named3/named3.go
Normal file
31
_test/named3/named3.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package named3
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type T struct {
|
||||||
|
A string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *T) Print() {
|
||||||
|
println(t.A)
|
||||||
|
}
|
||||||
|
|
||||||
|
type A http.Header
|
||||||
|
|
||||||
|
func (a A) ForeachKey() error {
|
||||||
|
for k, vals := range a {
|
||||||
|
for _, v := range vals {
|
||||||
|
fmt.Println(k, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a A) Set(k string, v []string) {
|
||||||
|
a[k] = v
|
||||||
|
}
|
||||||
@@ -17,11 +17,23 @@ func (b B) Test2() {
|
|||||||
fmt.Println("test2")
|
fmt.Println("test2")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b B) Test3() {
|
||||||
|
for k, vals := range b {
|
||||||
|
for _, v := range vals {
|
||||||
|
fmt.Println(k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
b := B{}
|
b := B{}
|
||||||
|
|
||||||
b.Test2()
|
b.Test2()
|
||||||
|
b["test"] = []string{"a", "b"}
|
||||||
|
b.Test3()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// test2
|
// test2
|
||||||
|
// test a
|
||||||
|
// test b
|
||||||
@@ -2,11 +2,11 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
_, err := ioutil.ReadFile("__NotExisting__")
|
_, err := os.ReadFile("__NotExisting__")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err.Error())
|
fmt.Println(err.Error())
|
||||||
}
|
}
|
||||||
9
_test/p2/p2.go
Normal file
9
_test/p2/p2.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package p2
|
||||||
|
|
||||||
|
type I interface {
|
||||||
|
isI()
|
||||||
|
}
|
||||||
|
|
||||||
|
type T struct{}
|
||||||
|
|
||||||
|
func (t *T) isI() {}
|
||||||
0
_test/p3/empty
Normal file
0
_test/p3/empty
Normal file
3
_test/p4/p4.go
Normal file
3
_test/p4/p4.go
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
package p4
|
||||||
|
|
||||||
|
var Value1 = "value1"
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user