2021年8月30日 一道 golang 切片面试题 为什么 sl[:5] 会返回底层数组的数据呢? 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 package main import "fmt" func main() { sl := make([]int, 0, 10) appendFn := func(s []int) { // 值传递, s 并不是 sl。 // 但数组是引用类型, 所以可以修改底层数组 fmt.Println("s ptr(old):", s) // [] s = append(s, 10, 20, 30) fmt.Println("s ptr(new):", s) // [10,20,30] } fmt.Println(sl) // [] appendFn(sl) fmt.Println(sl) // [] // 这里有点坑, 并不是取的 sl ,而是底……
阅读全文
2021年8月26日 golang 下划线完成对象的接口类型检查 在 Gin 源码中 有一行代码如下 1 var _ IRouter = &RouterGroup{} 乍一看, 是一个 赋值 操作, 但是前面又使用了 空白描述符(下划线) 。 这是什么意思呢? 答案是: 接口类型检查 在 《Effective GO》 Interface Check 中的描述有相关描述。 全文如下。 One place this situation arises is when it is necessary to guarantee within the package implementing the type that it actually satisfies the interface. If a type-for……
阅读全文
2021年8月26日 typescript 中的 const assertions const assertions - TypeScript 3.4 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // vue3 const dnsProviders = { "aliyun.com": "alidns", "tencent.com": "dnspod" } let data = reactive({ rootDomain: "aliyun.com" as const }) let dnsProvider = computed( () => { return dnsProviders[data.rootDomain] } ) 这个时候会, 提示 7053 错误, data.rootDomain 具有 any type, 不能被用作 key。 解决这个问题使用, 需要使用 typescript 中 const assertion 类型推断。 const assertion 类型推断。 字面量类型推断: 其类型为字面值类型。 例如这里的 hello 的类型是……
阅读全文
2021年8月25日 typescript 中的时间处理 在 typescript/ javasctipt 中, 时间 是一个 构造 函数, 需要通过 const dt = new Date(xxx) 进行初始化创建时间对象。 创建时间对象 1 2 3 4 5 6 7 8 9 10 // 获取当前时间对象 const now = new Date() // 将字符串时间转换为 Date 时间对象 const timeStr = '2021-08-23T02:42:17Z' const dt = new Date(timeStr) // 根据数字创建时间 const dt2 = new Date(Date.UTC(2006, 0, 2, 15, 4, 5)); console.log("event:::", dt2); 时间操作 获取时间对象的属性值 通过 getXXX() 方法, 可以……
阅读全文
2021年8月23日 golang 中的时间处理 在 golang 中有一个很重要的 格式化时间的字符串 2006-01-02T15:04:05Z07:00 , 这个也是 golang 默认时间模版模版中的 time.RFC3339 1 RFC3339 = "2006-01-02T15:04:05Z07:00" golang 中关于时间的处理, 用到了上面的 每一个 数字和字母。 需要特别注意的是, 时区用的是 7 而非 6 , 因为 6 已经在 年(2006) 中出现了 创建时间对象 time.Time 1 2 3 4 5 6 7 8 9 10 // 1. 创建当前时间对象 now := time.Now() //……
阅读全文
2021年8月20日 ginbind 的实现过程-一起来看gin源码吧 是的,没错。 如果你用过 gin 那么你一定知道,gin 中绑定参数的方式很零散。 c *gon.Context 给你提供了很多中方法, 例如BindHeader, BindURI 等等, 但是如果想要绑定 reqeust 中不同地方的参数, 那对不起咯,并没有。 另外, gin 中的 Bind 接口, 默认是包含了 参数验证 validate 功能的, 因此如果你……
阅读全文
2021年8月19日 ginbinder 一次绑定 Request 中所有需要的数据 Usage 废弃/不可用: 弃用原生 tag form tag。 保持: 使用 tag uri 绑定路径中的参数。 作用于某个字段 就是 example.com/:some/:path 中 冒号后面的 保持: 使用 tag header 绑定 header。 作用于某个字段 新增: 新增 tag query tag 绑定通过 Query 传递的参数。 作用于某个字段 就是 example.com/some/path?a=1&b=2 中 问号后面的那一串 新增: 新增 tag cookie 绑定 cookie 中 简单 的键……
阅读全文
2021年8月18日 go1.17 泛型尝鲜 语法格式如下, 需要使用 [T Ttype] 指定约束条件, 例如 [T any] 不做任何约束, [T MyInterface] 满足 MyInterface 的约束 接下来我们将尝试上述提到的内容。 1 2 3 func fname[T Ttype](args []T) T { // statement } 需要注意的是, 现在泛型在 go1.17 中依旧不是正式支持, 所以在 IDE 或者编辑器上会有报错。 编译需要指定额外的 -gcflags=-G=3 参数 1 go run -gcflags=-G=3 main.go 开始吧 不约束 any 首先,我们来……
阅读全文
2021年7月28日 golang gin 使用 context 实现 ioc gin 是一个流行的 golang webserver 的框架。 https://github.com/gin-gonic/gin gin 中 HandlerFunc (type HandlerFunc func(*Context)) 的使用随处可见, ex. Middleware , Handler 中。 1 2 3 4 router.GET("/user/:name", func(c *gin.Context) { name := c.Param("name") c.String(http.StatusOK, "Hello %s", name) }) 因此,根据之前 golang context 实现 IoC 容器经验, 使用 *gin.Context 作为 IoC 容器再好不过了。 标准库 context.Context 是一个接口(interface), gin.Context 是 gin 工程自己封装的的一个 struct, 并实现了该接口。 虽然……
阅读全文
2021年7月27日 golang 使用 Context 实现 IoC 容器 参考文章 控制反转(IoC)与依赖注入(DI) 指出了依赖注入可以降低程序的耦合性。 能更好的拆分功能与基础设施。 那么在 golang 中又怎么实现呢? 代码地址 golang-context-ioc.go 实现了一个 MysqlDriver 实现我们所有的数据存取操作。 并在全局域中实例化了一个对象 my。 在 main.go 中创建了一个 ctx := context.Background() 使用使用 ctx 作为 IoC 容器, 使……
阅读全文