判断io读取是否结束,尽量用if n==0这种方式,因为可以判断很多种情况

package main

import (
"fmt"
"io"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello"))
fmt.Println(r.Header)
} func main() {
resp, err := http.Get("http://www.baidu.com")
if err != nil {
return
}
buf := make([]byte, 4096)
results := ""
for {
n, err := resp.Body.Read(buf)
if n == 0 { //判断io读取是否结束,尽量用if n==0这种方式,因为可以判断很多种情况
break
}
if err != nil && err != io.EOF {
fmt.Println(err)
break
}
results += string(buf[:n])
}
fmt.Println(results)
}

nil是有类型和值得,var *int = nil,它底层数据结构为(*int,data)

接口为nil的充要条件为接口的运行时类型为nil,并且接口的运行时值为nil。这里将运行时的类型赋值为了File类型的指针

var w io.Writer

var f *os.File

w = f

fmt.Println(w == nil) //false

这里为什么是false呢?原因是当File类型的指针赋值给Writer接口时,接口的类型被赋值为File类型的指针,而类型描述符被赋值为nil,而一个接口为nil的充要条件为接口的运行时类型为nil,并且接口的运行时值为nil。这里将运行时的类型赋值为了File类型的指针,因此是false。这显然不符合我们的预期,换种说法,这显然不是我们想要的结果,那我们如何进行更改呢?只需要将f的编译时类型改为io.Writer即可。因为两种类型是相同的,因此w = f进行赋值的时候,并不会改变运行时类型,又因为两个的值都是nil,所以运行时的值为nil,这样的话w == nil 就显然为true了

当将空指针赋值给接口时,接口实例并不等于nil

当把一个空指针对象赋值给一个interface后,再判断!= nil就不再成立了
代码如下 package main import "fmt" type Person interface {
Name() string
} type ChenQiongHe struct {
} func (t *ChenQiongHe) Name() string {
return "雪山飞猪"
} func main() {
var test *ChenQiongHe
if test == nil {
fmt.Println("test == nil")
} else {
fmt.Println("test != nil")
}
//将空指针赋值给接口
var person Person = test
if person == nil {
fmt.Print("person == nil")
} else {
fmt.Print("person != nil")
}
}
运行结果 test == nil
person != nil
test本来是nil,赋值给person后居然不能再用nil判断了 解决方法
使用reflect包的IsNil判断,封装为一个能用方法 func IsNil(i interface{}) bool {
vi := reflect.ValueOf(i)
if vi.Kind() == reflect.Ptr {
return vi.IsNil()
}
return false
}

补充知识点:

每当有一个进程启动时,系统会自动打开三个文件:标准输入,标准输出,标准错误--对应三个文件:stdin,stdout,stderr,当运行程序结束,系统自动关闭这三个文件

结构体指针做函数返回值的时候

不能返回局部变量的地址值。局部变量保存在栈帧上,函数调用结束后,栈帧释放,局部变量的地址,不再受系统保护,随时可能分配给其他程序局部变量的值可以返回

内存对齐优化

https://www.cnblogs.com/sunsky303/p/11315429.html

结构体的地址等于首个元素的地址**

package main

import "fmt"

type Person struct {
name string
sex byte
age int
} func main() {
p := Person{"Jerry", '0', 26}
fmt.Printf("%p\n", &p) //0xc000004460
fmt.Printf("%p\n", &p.name) //0xc000004460
}
用*加类型去调用结构体函数
package main

import (
"fmt"
) type N struct {
int
} func (n N) test() {
fmt.Printf("%p\n%d\n", &n, n)
} func main() {
var n N = N{2}
fmt.Printf("%p\n%d\n", &n, n)
f1 := N.test
f2 := (*N).test //可用*加类型去调用函数
f1(n)
f2(&n)
}
for;true;{} go里面的while true**
var aa bool = true
c := 0
for ; aa; {
fmt.Print(20)
c++
if c > 10 {
aa = false
}
}
两个函数相同类型相同的条件是拥有相同的形参列表和返回值列表(列表的次序,个数和类型都相同)行参名可以不同,以下两个函数类型是相同的
func add(a,b int) int {
return a+b
}
func sub(x int,y int) (c int){
c = x-y;return c
}

可以通过type定义函数类型,函数类型变量可以作为函数的参数和返回值

type Op func(int,int) int
func add(a, b int) int {
return a+b
}
func do (f Op, a, b int) int{
return f(a, b)
} func main(){
a:=do(add, 1 ,2)
fmt.print(a)
}
主动调用os.exit(1) defer将不会执行
package main
import "os"
import "fmt" func main(){
defer func(){
fmt.Println("haha")
}()
os.Exit(1)
} //本函数不会打印haha

defer一般放到错误语句检查之后,尽量不要放到循环语句中,相对于普通的函数调用,defer需要间接的数据结构的支持,相对于普通函数有一定的性能损耗

Go奇技淫巧的更多相关文章

  1. C#开发奇技淫巧三:把dll放在不同的目录让你的程序更整洁

    系列文章 C#开发奇技淫巧一:调试windows系统服务 C#开发奇技淫巧二:根据dll文件加载C++或者Delphi插件 C#开发奇技淫巧三:把dll放在不同的目录让你的程序更整洁 程序目录的整理 ...

  2. 【CSS进阶】box-shadow 与 filter:drop-shadow 详解及奇技淫巧

    box-shadow 在前端的 CSS 编写工作想必十分常见.但是 box-shadow 除去它的常规用法,其实还存在许多不为人知的奇技淫巧. 喜欢 markdown 版本的可以戳这里. box-sh ...

  3. JS~~~ 前端开发一些常用技巧 模块化结构 &&&&& 命名空间处理 奇技淫巧!!!!!!

    前端开发一些常用技巧               模块化结构       &&&&&     命名空间处理 奇技淫巧!!!!!!2016-09-29    17 ...

  4. MySQL优化的奇技淫巧之STRAIGHT_JOIN

    原文地址:http://huoding.com/2013/06/04/261 问题 通过「SHOW FULL PROCESSLIST」语句很容易就能查到问题SQL,如下: SELECT post.* ...

  5. C++的一个奇技淫巧

    C++如何写一个函数,得到一个数组的长度呢? size_t GetArrayLength(int Array []) { return sizeof(Array)/sizeof(Array[0]);  ...

  6. linux奇技淫巧

    用着用着就发现,linux的每个命令都是那么的深奥而富有技巧,实用而淫荡..真可谓奇技淫巧.... 初学的真不易掌握... http://www.cnblogs.com/include/archive ...

  7. Git的奇技淫巧🙈

    Git的奇技淫巧

  8. css中各种居中的奇技淫巧总结

    css中各种居中的奇技淫巧总结   第一种,在固定布局中比较常用的技巧设置container的margin:0 auto:   第二种(从布局中入手)   css .outer{ height:200 ...

  9. SVN与TortoiseSVN实战:属性的奇技淫巧(二)

    硬广:<SVN与TortoiseSVN实战>系列已经写了七篇,本系列结合TortoiseSVN对SVN中容易被忽视的部分进行了详解. 关于属性的奇技淫巧较多,分为两篇来写,第一篇详见< ...

  10. SVN与TortoiseSVN实战:属性的奇技淫巧(一)

    硬广:<SVN与TortoiseSVN实战>系列已经写了六篇,本系列结合TortoiseSVN对SVN中容易被忽视的部分进行了详解,预计再用三.四篇来结束这个系列. 本篇详解一下SVN的属 ...

随机推荐

  1. strings包 — 汇总

    转自:https://www.jb51.net/article/148388.htm strings 包中的函数和方法 // Count 计算字符串 sep 在 s 中的非重叠个数 // 如果 sep ...

  2. python中将已有链接的视频进行下载

    使用python爬取视频网站时,会得到一系列的视频链接,比如MP4文件.得到视频文件之后需要对视频进行下载,本文写出下载视频文件的函数. 首先导入requests库,安装库使用pip install ...

  3. 08-Maps

    Maps map 是在 Go 中将值(value)与键(key)关联的内置类型.通过相应的键可以获取到值.Maps类似于python中的字典 Maps定义 maps的key值必须是可hash(就是不可 ...

  4. Altium Designer 复制报错-奇怪的问题解决办法

    之前AD画原理图复制元件正常使用,今天使用时复制弹出了错误.很是诧异! 各种搜索查找问题,发现或许是因为前一段时间把,电脑上的所有打印机都删除了导致的. 就安装了一个打印机. 再复制,就不报错了. 或 ...

  5. 关于django操作orm的一些事--反向生成orm、连接多个数据库

    1. django反向生成orm的类代码 使用命令python manage.py inspectdb > app01/models.py,注意,我这里的app01是app的名字. 2.djan ...

  6. linux BufferedImage.createGraphics()卡住不动

    项目应用服务器tomcat7,在开发(windows).测试环境(linux 64bit)均正常.在生产环境(linux 64bit)一直启动不起来,也没有报错. 最终定位问题:执行到buffered ...

  7. Java中 单例模式(singleton)

    Java Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在. 使用Singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收( ...

  8. gitlab用户登录与AD域用户集成

    ---恢复内容开始--- 编辑gitlab.rb文件 sudo vi /etc/gitlab/gitlab.rb 下图是我编辑的内容示例(仅供参考): 编辑以下内容: gitlab_rails['ld ...

  9. MySQL安装后的初始优化

    mysql数据库在安装之后,有一些内置的库(test库).用户(如root@localhost.localdomain)是不需要的,而且在Linux系统上,yum安装的mysql是默认无root密码的 ...

  10. 过渡属性transition

    过渡属性:使元素变化过程可见 transition: all 1s;元素所有变化过程都可见 transition: 1s;元素所有变化过程都可见 transition: 指定属性 2s 1s;指定属性 ...