范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

Golang58个坑高级篇5258

  52.使用指针作为方法的 receiver 53.更新 map 字段的值 54.nil interface 和 nil interface 值 55.堆栈变量 56.GOMAXPROCS、Concurrency(并发)and Parallelism(并行) 57.读写操作的重新排序 58.优先调度 52.使用指针作为方法的 receiver
  只要值是可寻址的,就可以在值上直接调用指针方法。即是对一个方法,它的 receiver 是指针就足矣。
  但不是所有值都是可寻址的,比如 map 类型的元素、通过 interface 引用的变量: type data struct {     name string }  type printer interface {     print() }  func (p *data) print() {     fmt.Println("name: ", p.name) }  func main() {     d1 := data{"one"}     d1.print()    // d1 变量可寻址,可直接调用指针 receiver 的方法      var in printer = data{"two"}     in.print()    // 类型不匹配      m := map[string]data{         "x": data{"three"},     }     m["x"].print()    // m["x"] 是不可寻址的    // 变动频繁 }
  cannot use data literal (type data) as type printer in assignment:
  data does not implement printer (print method has pointer receiver)
  cannot call pointer method on m["x"]
  cannot take the address of m["x"] 53.更新 map 字段的值
  如果 map 一个字段的值是 struct 类型,则无法直接更新该 struct 的单个字段: // 无法直接更新 struct 的字段值 type data struct {     name string }  func main() {     m := map[string]data{         "x": {"Tom"},     }     m["x"].name = "Jerry" }
  cannot assign to struct field m["x"].name in map
  因为 map 中的元素是不可寻址的。需区分开的是,slice 的元素可寻址: type data struct {     name string }  func main() {     s := []data{{"Tom"}}     s[0].name = "Jerry"     fmt.Println(s)    // [{Jerry}] }
  注意:不久前 gccgo 编译器可更新 map struct 元素的字段值,不过很快便修复了,官方认为是 Go1.3 的潜在特性,无需及时实现,依旧在 todo list 中。
  更新 map 中 struct 元素的字段值,有 2 个方法: 使用局部变量 // 提取整个 struct 到局部变量中,修改字段值后再整个赋值 type data struct {     name string }  func main() {     m := map[string]data{         "x": {"Tom"},     }     r := m["x"]     r.name = "Jerry"     m["x"] = r     fmt.Println(m)    // map[x:{Jerry}] }使用指向元素的 map 指针 func main() {     m := map[string]*data{         "x": {"Tom"},     }      m["x"].name = "Jerry"    // 直接修改 m["x"] 中的字段     fmt.Println(m["x"])    // &{Jerry} }
  但是要注意下边这种误用: func main() {     m := map[string]*data{         "x": {"Tom"},     }     m["z"].name = "what???"          fmt.Println(m["x"]) }
  panic: runtime error: invalid memory address or nil pointer dereference 54.nil interface 和 nil interface 值
  虽然 interface 看起来像指针类型,但它不是。interface 类型的变量只有在类型和值均为 nil 时才为 nil
  如果你的 interface 变量的值是跟随其他变量变化的(雾),与 nil 比较相等时小心: func main() {     var data *byte     var in interface{}      fmt.Println(data, data == nil)    //  true     fmt.Println(in, in == nil)    //  true      in = data     fmt.Println(in, in == nil)    //  false    // data 值为 nil,但 in 值不为 nil }
  如果你的函数返回值类型是 interface,更要小心这个坑: // 错误示例 func main() {     doIt := func(arg int) interface{} {         var result *struct{} = nil         if arg > 0 {             result = &struct{}{}         }         return result     }      if res := doIt(-1); res != nil {         fmt.Println("Good result: ", res)    // Good result:           fmt.Printf("%T ", res)            // *struct {}    // res 不是 nil,它的值为 nil         fmt.Printf("%v ", res)            //      } }   // 正确示例 func main() {     doIt := func(arg int) interface{} {         var result *struct{} = nil         if arg > 0 {             result = &struct{}{}         } else {             return nil    // 明确指明返回 nil         }         return result     }      if res := doIt(-1); res != nil {         fmt.Println("Good result: ", res)     } else {         fmt.Println("Bad result: ", res)    // Bad result:       } }55.堆栈变量
  你并不总是清楚你的变量是分配到了堆还是栈。
  在 C++ 中使用 new 创建的变量总是分配到堆内存上的,但在 Go 中即使使用 new()、make() 来创建变量,变量为内存分配位置依旧归 Go 编译器管。
  Go 编译器会根据变量的大小及其 "escape analysis" 的结果来决定变量的存储位置,故能准确返回本地变量的地址,这在 C/C++ 中是不行的。
  在 go build 或 go run 时,加入 -m 参数,能准确分析程序的变量分配位置:
  56.GOMAXPROCS、Concurrency(并发)and Parallelism(并行)
  Go 1.4 及以下版本,程序只会使用 1 个执行上下文 / OS 线程,即任何时间都最多只有 1 个 goroutine 在执行。
  Go 1.5 版本将可执行上下文的数量设置为 runtime.NumCPU() 返回的逻辑 CPU 核心数,这个数与系统实际总的 CPU 逻辑核心数是否一致,取决于你的 CPU 分配给程序的核心数,可以使用 GOMAXPROCS 环境变量或者动态的使用 runtime.GOMAXPROCS() 来调整。
  误区:GOMAXPROCS 表示执行 goroutine 的 CPU 核心数,参考文档
  GOMAXPROCS 的值是可以超过 CPU 的实际数量的,在 1.5 中最大为 256 func main() {     fmt.Println(runtime.GOMAXPROCS(-1))    // 4     fmt.Println(runtime.NumCPU())    // 4     runtime.GOMAXPROCS(20)     fmt.Println(runtime.GOMAXPROCS(-1))    // 20     runtime.GOMAXPROCS(300)     fmt.Println(runtime.GOMAXPROCS(-1))    // Go 1.9.2 // 300 }57.读写操作的重新排序
  Go 可能会重排一些操作的执行顺序,可以保证在一个 goroutine 中操作是顺序执行的,但不保证多 goroutine 的执行顺序: var _ = runtime.GOMAXPROCS(3)  var a, b int  func u1() {     a = 1     b = 2 }  func u2() {     a = 3     b = 4 }  func p() {     println(a)     println(b) }  func main() {     go u1()    // 多个 goroutine 的执行顺序不定     go u2()         go p()     time.Sleep(1 * time.Second) }
  运行效果:
  如果你想保持多 goroutine 像代码中的那样顺序执行,可以使用 channel 或 sync 包中的锁机制等。 58.优先调度
  你的程序可能出现一个 goroutine 在运行时阻止了其他 goroutine 的运行,比如程序中有一个不让调度器运行的 for 循环: func main() {     done := false      go func() {         done = true     }()      for !done {     }      println("done !") }
  for 的循环体不必为空,但如果代码不会触发调度器执行,将出现问题。
  调度器会在 GC、Go 声明、阻塞 channel、阻塞系统调用和锁操作后再执行,也会在非内联函数调用时执行: func main() {     done := false      go func() {         done = true     }()      for !done {         println("not done !")    // 并不内联执行     }      println("done !") }
  可以添加 -m 参数来分析 for 代码块中调用的内联函数:
  你也可以使用 runtime 包中的 Gosched() 来 手动启动调度器: func main() {     done := false      go func() {         done = true     }()      for !done {         runtime.Gosched()     }      println("done !") }

浅谈释放压力最好的办法面对日益严峻的职场压力,亲朋关系,我们难免有情绪不好的时候,这个时候我们应该以什么样的心态和方式来面对呢?按照传统的看法,一个人在人前哭泣流泪,就意味着他将自己的缺陷和柔弱暴露在人权力关进制度的笼子和透明公开是对人民最好的交代权力的游戏3。这个世界上拥有最大力量的是国家,拥有最大权力的也是国家。国家由政府和人民组成。政府是领头羊,是先锋队。人民是基础,是生产力的代表,是最具创新创造的保障。如果说权力是人楹联专辑黄河三角洲诗词周刊(2023第4辑)编者按天地风霜尽,乾坤气象和。历添新岁月,春满旧山河(明叶颙)。欣值癸卯年春节来临之际,滨州市诗词学会楹联专业委员会积极响应和落实党的二十大报告中关于传承中华优秀传统文化,不断提升安全又有趣!禅城首个儿童友好示范街今亮相1月18日,佛山市禅城区首个儿童友好示范街正式开街。该示范街坐落在禅城区石湾镇街道的深华路段,设有护学长廊智慧潮汐车道一米标识等适儿化公共设施,打造形成15分钟安学护学圈,全方位保暖心!2023年春风行动一瞥文丨中国劳动保障报记者赵泽众2023年1月,一年一度的春风行动如约而至。一路春风相伴,就业返岗无忧。2023年的春风行动,尊重民意关注民情致力民生。各地人社部门迅速组织密集招聘活动2006年,20岁广东女子嫁北大精英,婚后连生7胎,扬言不生浪费2006年,广东20岁打工妹张荣荣在嫁给北大毕业的丈夫后,接连为他生下七个孩子,引发网友议论。她表示丈夫智商高达140,不想浪费了丈夫的好基因,如果可以,自己以后没准还会生。一个生敢在湖南大家谈(三)敢在湖南大家谈(一)敢在湖南大家谈(二)编者按2022年12月6日,中共中央政治局召开会议,强调要激发全社会干事创业活力,让干部敢为地方敢闯企业敢干群众敢首创。敢字蕴含的精神品质,新年上UC,来打造一款符合你习惯的专属浏览器在日常上网的过程中,浏览器应该是必不可缺的软件之一。就拿小编来说,通勤路上会看些新闻或小说来打发时间,晚上到家刷刷视频,都是通过浏览器来进行的。而市面上浏览器众多,在经过对比后,小清华和北大的区别?本人也是经过了深思熟虑,在每个日日夜夜思考这个问题。博曾经提到过,一次失败,只是证明我们成功的决心还够坚强。维这句话看似简单,但其中的阴郁不禁让人深思。问题的关键究竟为何?迈克尔F我的2022,有点难过我的生活也是头条2022年,是疫情最严重的一年,对世界人民给予重创与考验。一大部分人因感染新冠生病了,有的阳康了,有的则留下了严重的后遗症,有的甚至因此永远离开人世。同时,因疫情原人最大的恶,是见不得别人好鲁迅先生曾在文章中写到很多人都见不得别人过好日子,自己没的,若别人有自己就会心生恨,若别人正极力追求一个自己没有却也十分想要的东西便会极力撺掇说此物不好。嫉妒是人之常情,或多或少都
霸屏难关掉跳跳躲猫猫摇摇就会跑这样的弹窗还要飞多久?视频加载中互联网弹窗广告是指打开网页电脑软件手机APP等自动弹出的广告。尽管多年的治理让弹窗广告问题有所改善,但总体来看,弹窗广告依旧存在霸屏关不掉躲猫猫等现象。记者观察发现,弹窗iPhone15Plus渲染图曝光标配灵动岛外形更圆润CNMO新闻继iPhone15Pro系列后,iPhone15Plus的渲染图也被外媒曝光。通过外媒公布的图片来看,iPhone15Plus的大小与iPhone14Plus相同,同时公安鄠邑分局经侦大队集中发还15万余元涉案财物阳光讯(记者张京)2月21日上午,公安鄠邑分局经侦大队举行涉案财物集中发还仪式,经侦大队大队长郑伟超通报了三起案件侦办情况,分局副局长李飞将两起合同诈骗案一起信用卡诈骗案件追回的1美对台加紧准殖民地化!以和平拒绝统一,以侵略否定内政文彭开林美国对台湾的动作越来越多,众议院议长麦卡锡扬言春季进访台湾的余音未消,据报道美国还将大幅提高部署台湾的美军人数,白宫对此既不否认也不证实。美国国务卿布林肯近日在一个讨论会上客户不幸罹患重疾太平理赔服务获赞扬鲁网2月24日讯近日,太平人寿的客服柜面收到了一面写有理赔迅速服务周到的锦旗。原来,这是客户王女士为表达对太平人寿的感激之情,特意委托家人来表示感谢。在2021年初,王女士在太平人万里驰援土耳其中国援助彰显大国担当当地时间2月6日,土耳其叙利亚遭遇百年来最严重的强烈地震,截至目前,余震已造成两国数万人遇难。中国政府在第一时间启动紧急人道主义援助机制,派出中国救援队参与救援,向灾区运送抗震救灾全国人大代表马慧娟记录脱贫故事的拇指作家不久前,80后农民作家马慧娟向出版社交付了自己的第六本书的书稿。2022年9月以来,她连续写作5个月,完成了这本约8万字的儿童小说吊起来的村庄。书中内容与宁夏实施的吊庄移民行动有关百万年薪聘导游浙江开化有妙招考察点位拍摄短片记录要点春节假期一结束,浙江省开化县各景区景点就迎来20位导游。他们带着挖掘景区景点故事寻找旅游营销亮点的任务,开始踩线活动。去年12月,开化县向全国广发英雄帖百万董卿摊上大事了,其富豪丈夫因被国企追债沦为老赖据中国执行信息公开网,上海市浦东新区人民法院近日发布限制消费令,限制览海控股及览海控股法定代表人密春雷不得实施高消费及非生活和工作必需的消费行为。密春雷2003年创立览海控股并担任父母爱情剧中只有两个镜头一句台词,而她背后却有哀婉的故事父母爱情是由刘静编剧,孔笙执导实力派演员郭涛梅婷刘琳任帅刘天池等主演的家庭情感大剧,以上世纪五十年代直至新世纪之初时代沧桑巨变下我的父母的爱情为主线,演绎了几个家庭两代中国人的平凡13岁,一夜爆红,却被张艺谋当场劝退娱乐圈24年后,最丑谋女郎变成了这样提到谋女郎,肯定大家都会先想到巩俐章子怡倪妮周冬雨等等。但是,有这么一位花期很短的谋女郎,13岁,一夜爆红,却被张艺谋当场劝退娱乐圈。张艺谋甚至多次在媒体面前直言长得不好看,身材也