随笔 - 56  文章 - 0 评论 - 0 阅读 - 50743

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package stack
 
import "errors"
 
type Stack []interface{}
 
func (s *Stack) Len() int {
    return len(*s)
}
 
func (s *Stack) Cap() int {
    return cap(*s)
}
 
func (s *Stack) Push(x interface{}) *Stack {
 
    *s = append(*s, x)
 
    /**
 
    如果改为
    z := append(*s, x)
    s = &z
 
    1. 不将函数返回值赋给一个变量,而是直接对一个函数取地址:象这样:s = &(append(*s,x)) 是不允许的
    原因可能是:函数的返回值是一个在函数内部作用域的局部变量,在函数结束后如果没有传值到外部调用者的话作用域就会结束(同时空间被GC回收)
    对这样的局部变量取地址是不行的。
    如果返回值直接是一个指针(地址) 当然可以直接赋给外部变量,所以应该可以对返回指针的函数取值 如下
        func foo1() *int { x := 4; return &x }
        func foo2() int  { x := 4; return x }
 
        fmt.Println(*foo1()) //ok
        fmt.Println(&foo2()) //no
 
 
 
    2. 直接修改地址指向,在外部调
        s := stack.Stack{1, 2, 3}
        s.Push(4).Push(5).Push(6)
        fmt.Println(s)
    返回的仍然是 {1,2,3}
 
    原因是:方法的接受者虽然是指针,但方法内部只不过是将地址的值传值引用进来,
    在方法内部你可以利用这个传进来的地址值 对地址所在位置的内存进行修改,但你如果改变地址指向本身
    却是对外部没有影响的,总之从这点上看,以前学C语言时有个高人说过:
    “本质上,函数其实都是传值调用的,只不过有时传递是变量值,有时传的是地址值”
     */
 
    return s
}
 
func (s *Stack) Top() (interface{}, error) {
 
    n := s.Len()
    if n == 0 {
        return nil, errors.New("can not get top from an empty stack")
    }
 
    return (*s)[n-1], nil
}
 
func (s *Stack) Pop() (interface{}, error) {
 
    n := s.Len()
    if n == 0 {
        return nil, errors.New("can not pop an empty stack")
    }
 
    top := (*s)[n-1]
    *s = (*s)[:n-1]
 
    return top, nil
}

  

posted on   scala  阅读(162)  评论(0)    收藏  举报
编辑推荐:
· 通过一个DEMO理解MCP(模型上下文协议)的生命周期
· MySQL下200GB大表备份,利用传输表空间解决停服发版表备份问题
· 记一次 .NET某固高运动卡测试 卡慢分析
· 微服务架构学习与思考:微服务拆分的原则
· 记一次 .NET某云HIS系统 CPU爆高分析
阅读排行:
· AI浏览器自动化实战
· 让 AI 对接 MySQL 数据库实现快速问答对话
· C#/.NET/.NET Core技术前沿周刊 | 第 34 期(2025年4.7-4.13)
· .NET周刊【3月第4期 2025-03-23】
· 通过一个DEMO理解MCP(模型上下文协议)的生命周期
点击右上角即可分享
微信分享提示