• 咖啡色的羊驼
    2018-09-21
    好久没留言了,

    1.断言判断value.(type)
    2.if的判断的域和后面跟着的花括号里头的域。和函数雷同,参数和花括号里头的域同一个

    作者回复: 好,继续加油吧。

    
     13
  • Zzz
    2019-05-15
    个人理解: for .. range .. 实际上可以认为是方法调用的语法糖,range后面的变量就是方法参数,对于数组类型的变量,传入的参数是数组的副本,更新的是原数组的元素,取的是副本数组的元素;对于切片类型的变量,传入的参数是切片的副本,但是它指向的底层数组与原切片相同,所以取的元素和更新的元素都是同一个数组的元素。
    
     6
  • 澎湃哥
    2018-11-29
    好像还没有人回答数组变切片的问题,贴一下运行结果吧:
    i:0, e:1
    i:1, e:3
    i:2, e:6
    i:3, e:10
    i:4, e:15
    i:5, e:21
    [22 3 6 10 15 21]

    每次循环打印了一个索引和值,看起来 range 切片的话,是会每次取 slice[i] 的值,但是应该还是发生了拷贝,不能通过 e 直接修改原值。
    展开
    
     5
  • Leon📷
    2018-10-22
    val.(type)需要提前将类型转换成interface{},一楼的留言有点问题
    
     3
  • 大王叫我来巡山
    2019-09-09
    了解这些只能证明您对这个语言足够的了解,但是实际中谁会写这么蛋疼的代码呢,这一篇通篇其实说明的还是go语言中关于类型转换的内容

    作者回复: 这些语法细节你要是不注意的话,说不定什么时候就会“踩坑”。文章中的代码是为了演示原理而设计的,因此不一定适用于生产。

    你可以去看看哪些热门开源项目的代码,里面仍然会有体现这些知识点的代码。所以不充分理解这些,可能看复杂些的项目源码都费劲。

     1
     2
  • 江山如画
    2018-10-08
    第一个问题,在类型switch语句中,如何对被判断类型的那个值做类型转换,尝试在 switch 语句中重新定义了一个 uint8 类型的变量和被判断类型的值做加法操作,一共尝试了三种方法,发现需要使用 type assertion 才可以,强转或者直接相加都会出错。

    转换语句是:val.(uint8)

    完整验证代码:

    val := interface{}(byte(1))
    switch t := val.(type) {
    case uint8:
        var c uint8 = 2

        //use type assertion
        fmt.Println(c + val.(uint8))

        //invalid operation: c + val (mismatched types uint8 and interface {})
        //fmt.Println(c + val)

        //cannot convert val (type interface {}) to type uint8: need type assertion
        //fmt.Println(c + uint8(val))

    default:
        fmt.Printf("unsupported type: %T", t)
    }

    第二个问题,在if语句中,初始化子句声明的变量的作用域是在该if语句之内,if语句之外使用该变量会提示 “undefined”。

    验证代码:

    m := make(map[int]bool)
    if _, ok := m[1]; ok {
        fmt.Printf("exist: %v\n", ok)
    } else {
        fmt.Printf("not exist: %v\n", ok)
    }

    //fmt.Println(ok) //报错,提示 undefined: ok
    展开
     1
     2
  • 茶底
    2018-09-23
    老师什么时候讲逃逸分析啊
    
     2
  • 博博
    2019-07-23
    老师遇到一个问题,希望能帮忙解答下!
    您在文章中说range表达式的结果值是会被复制的,那么是所有的都会被复制么? 我看了资料,发现字典和通道类型好像没有发生复制!

    // Lower a for range over a map.
    // The loop we generate:
    // var hiter map_iteration_struct
    // for mapiterinit(type, range, &hiter); hiter.key != nil; mapiternext(&hiter) {
    // index_temp = *hiter.key
    // value_temp = *hiter.val
    // index = index_temp
    // value = value_temp
    // original body
    // }
    很是疑惑,希望能得到指点!谢谢
    展开

    作者回复: 你看的是 Go 的源码吗?我没找到这段代码。不过我看了下 mapiterinit 函数的代码。其中还是有复制的。只不过,对于这些引用类型的值来说,即使有复制也只会复制一些指针而已,底层数据结构是不会被赋值的。

    
     1
  • hiyanxu
    2018-12-23
    老师,我想问一下,range的副本,是说k、v是副本,还是被迭代的数组是副本?
    我自己测试在for的里面和外面数组地址是一样的

    作者回复: 迭代变量是副本。另外在Go程序里的变量地址是不能完全说明问题的,因为goroutine的栈空间有可能会被优化。

    
     1
  • 后端进阶
    2018-09-21
    真的很喜欢go的语法与简洁的哲学
    
     1
  • My dream
    2018-09-21
    Go1.11已经正式发布,最大的一个亮点是增加了对WebAssembly的实验性支持。老师要讲一下不?我们都不懂这个有什么意义

    作者回复: 主要是写Web端的时候有些用,不过我不觉得用处很大,因为现在大型网站都是前后端分离的。最后我视情况而定吧。

    
     1
  • Dr.Li
    2018-09-21
    感觉go的语法有点变态啊

    作者回复: 要包容:)工具而已。

    
     1
  • Felix
    2019-12-09
    关于数组变切片那个地方。我理解如下:切片自己不拥有任何数据,它只是底层数组的一种表示,对切片的任何操作都会被反映到底层数组中去。
    package main

    import "fmt"

    func main() {

        numbers3 := []int{1, 2, 3, 4, 5, 6}
        maxIndex3 := len(numbers2) - 1 //6-1= 5
        for i, e := range numbers3 { // 0:1 1:2 2:3 3:4 4:5 5:6
            if i == maxIndex3 { // 5
                numbers3[0] += e // 0,7
            } else {
                numbers3[i+1] += e // 1:3
            }
            // 0:1 1:(1+2)3 2:3 3:4 4:5 5:6
            // 0:1 1:3 2:(3+3)6 3:4 4:5 5:6
            // 0:1 1:3 2:6 3:(6+4)10 4:5 5:6
            // 0:1 1:3 2:6 3:10 4:(10+5)15 5:6
            // 0:1 1:3 2:6 3:10 4:15 5:(15+6)21
            // 0:(21+1)22 1:3 2:6 3:10 4:15 5:21
            // 22 3 6 10 15 21
        }
        fmt.Println(numbers3)
    }
    展开

    作者回复: 对,所以我们才称切片为引用类型。它本身只是底层数组及其存储状态的一种描述。

    
    
  • benying
    2019-06-04
    学习到一些平时没注意的细节,学习老师
    
    
  • Geek_1ed70f
    2019-02-26
    按位或

    有错别字 += 写成了 |=

    作者回复: 这就是按位或啊

    
    
  • 虢國技醬
    2019-01-21
    打卡
    
    
  • jacke
    2018-10-24
    switch进行有限的转化不是很明白?value1里面switch的语句不能从int转换为int8、那value2里面case语句又可以从int转换为int8?还有借口转换如何判定呢?
     1
    
  • yandongxiao
    2018-09-27
    咖啡色的羊驼的答案貌似是错误的吧?
    1. 在类型switch语句中,t := value6.(type);匹配到哪个case表达式,t就会是哪种具体的数据类型;
    2. 在if语句中,子句声明的变量的作用域 比 随后的花括号内的变量的的作用域 更大
        if a := 10; a > 0 {
            a := 20
            println(a)
        }
    反证法:如果咖啡色的羊驼说的对,上面的语句不应该编译通过才对。

    关于2这个细微的差异,也适用于for i:=0; i<10; i++ 语句。
    在for语句中的使用匿名函数,很可能出现“loop variable capture”问题。根本原因也是i的作用域与{}中的变量的作用域是不同的。
    展开
    
    
  • hua
    2018-09-21
    把总结结论放在最前面再看主体内容会容易理解得多。
    
    
我们在线,来聊聊吧