V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
liian2019
V2EX  ›  Go 编程语言

刚学 go 语言,请大家帮忙看看我下面这段代码问题是什么

  •  
  •   liian2019 · 289 天前 · 2261 次点击
    这是一个创建于 289 天前的主题,其中的信息可能已经有所发展或是发生改变。
    type MyFunc func(int, int) int
    
    func calc3(x, y int) int {
    	return x + y
    }
    
    func execTime(call MyFunc) MyFunc {
    	return func(int, int) int {
    		start := time.Now()
    		r := call(x, y)
    		fmt.Println("程序执行耗时", time.Since(start))
    		return r
    	}
    }
    
    func TestFuncLearn(t *testing.T) {
    	wrapper := execTime(calc3)
    	r := wrapper(1, 2)
    	fmt.Println("计算结果为", r)
    	fmt.Println("计算结果 2 为", calc3(1, 2))
    }
    

    执行结果..

    === RUN   TestFuncLearn
    程序执行耗时 125ns
    计算结果为 5
    计算结果 2 为 3
    --- PASS: TestFuncLearn (0.00s)
    PASS
    

    请问一下问什么执行结果是 5 呢,debug 进去,x=2 ,y=3,人傻了

    18 条回复    2024-03-06 09:29:27 +08:00
    ben1iu
        1
    ben1iu  
       289 天前
    你 execTime 中 call(x,y) 这个 x y 定义在函数外了吧
    liian2019
        2
    liian2019  
    OP
       289 天前
    知道了,内部类里面的 x,y 不是局部变量,而是使用的外部的全局变量。。。
    liian2019
        3
    liian2019  
    OP
       289 天前
    @ben1iu 是的是的,感谢大佬
    xhatt510
        4
    xhatt510  
       289 天前
    什么意思?代码没放全?
    liian2019
        5
    liian2019  
    OP
       289 天前
    @xhatt510 不是的,匿名方法定义是 func(int, int) int ,里面的方法 call(x, y)使用的不是匿名方法的入参,而是一个别的文件的 xy 变量
    liian2019
        6
    liian2019  
    OP
       289 天前
    ```go
    return func(int, int) int {
    start := time.Now()
    r := call(x, y)
    fmt.Println("程序执行耗时", time.Since(start))
    return r
    }
    ```
    话说 go 语言尽然允许这样写,那我 call 方法如何取到匿名方法的入参呢
    flyqie
        7
    flyqie  
       289 天前 via Android
    @liian2019 #6

    对 call 这个 function 是没有任何区别的。
    qqqqdddd
        8
    qqqqdddd  
       289 天前
    ```
    package main

    import (
    "fmt"
    "time"
    )

    func main() {
    wrapper := execTime(calc3)
    r := wrapper(1, 2)
    fmt.Println("计算结果为", r)
    fmt.Println("计算结果 2 为", calc3(1, 2))
    }

    type MyFunc func(int, int) int

    func calc3(x, y int) int {
    return x + y
    }

    func execTime(call MyFunc) MyFunc {
    return func(x, y int) int {
    start := time.Now()
    r := call(x, y)
    fmt.Println("程序执行耗时", time.Since(start))
    return r
    }
    }

    ```
    liian2019
        9
    liian2019  
    OP
       289 天前
    @qqqqdddd 嗯嗯 已经知道原因了谢谢
    xhatt510
        10
    xhatt510  
       289 天前
    @liian2019 #5 那不就是没给全吗?
    liian2019
        11
    liian2019  
    OP
       289 天前
    @xhatt510 本意是用匿名方法的入参,不知道外部也正好有 xy 这两个参数
    realJamespond
        12
    realJamespond  
       288 天前
    func execTime(call MyFunc) MyFunc {
    return func(int, int) int {
    start := time.Now()
    r := call(x, y)
    realJamespond
        13
    realJamespond  
       288 天前
    func execTime(call MyFunc) MyFunc {
    return func(int, int) int {
    start := time.Now()
    r := call(x, y)

    这里 x,y 没定义的话应该报错
    lasuar
        14
    lasuar  
       288 天前
    业务里面禁止写这种花里胡哨的代码。
    liian2019
        15
    liian2019  
    OP
       282 天前
    @realJamespond 嗯嗯 是的 在包的别的文件定义了 xy ,我自己都搞忘了
    liian2019
        16
    liian2019  
    OP
       282 天前
    @lasuar 跟着学的哈哈,业务里面感觉一些通用的工具包应该这样写问题也不大
    lasuar
        17
    lasuar  
       282 天前
    @liian2019 业务代码和工具包有着根本的区别,前者是需要经常阅读和偶尔修改的,后者基本不需要你做修改亦不关心可读性。可以掌握,但注意使用场景。
    liian2019
        18
    liian2019  
    OP
       280 天前
    @lasuar 嗯嗯
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4378 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 09:50 · PVG 17:50 · LAX 01:50 · JFK 04:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.