- 博客(161)
- 收藏
- 关注
原创 [go] Stringer 类型
Stringer是Golang的fmt包中的一个类型。Stringer由任何具有String方法的值来实现。实现Stringer的类型与字符串的打印方式相同。Stringer会返回一个字符串。
2024-09-27 16:06:49 241
原创 [go] 模版方法模式
在一个方法中定义了一个算法的骨架,而将一些步骤延迟到子类中。模版方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
2024-09-23 10:23:01 520
原创 [go] 责任链模式
责任链模式是一种行为设计模式,允许你将请求沿着处理者链进行发送。收到请求后,每个处理者均可对请求进行处理,或将其传递给链上的下个处理者。
2024-09-18 21:46:51 409
原创 [go] 命令模式
将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。模型说明触发者类负责对请求进行初始化,其中必须包含一个成员变量来存储对于命令对象的引用。触发命令,而不同接受者直接发送请求。注意,发送者并不负责创建命令对象:它通常会通过构造函数从客户端处获得预先生成的命令。命令接口通常仅声明一个执行命令的方法。具体命令会实现各种类型的请求。具体命令自身并不完成工作,而是会将调用委派给一个业务逻辑对象。但为了简化代码,这些类可以进行合并。
2024-09-17 23:01:17 684
原创 [go] 单例模式
确保类只有一个实例,并提供一个全局的访问点。单例(Singleton)类声明了一个名为getInstance的方法来返回其所属类的一个相同实例。单例的构造函数必须对客户端的代码隐藏。调用getInstance方法必须是获取单例对象的唯一方式。
2024-09-17 23:00:45 372
原创 go 语言实现依赖注入
依赖注入和控制反转恰恰相反,它是一种具体的编码技巧。我们不通过 new 的方式在类内部创建依赖类的对象,而是将依赖的类对象在外部创建好之后,通过构造函数、函数参数等方式传递(或注入)给类来使用。DI(依赖性注入)是一种技术,当你的模块间接地接受依赖性。他们不知道依赖的实现,只知道接口。
2024-09-14 22:12:20 376
原创 Go中更安全的枚举
Go让你用iota来使用枚举。虽然Go是明确的,但iota似乎相对模糊。如果你以任何其他方式对const组进行排序,你会引入副作用。在上面的例子中,你仅仅对第一个参数Guest赋值了。你可以显式地给每个值分配一个数字来避免这个问题,但这使iota变得过时。iota对于用位运算定义的参数也很有效。位掩码是有效的,有时也很有帮助。然而,在大多数Web应用程序中,它的使用情况与枚举不同。通常情况下,你可以将所有的角色存储在一个列表中。它也会更容易阅读。
2024-09-13 20:42:22 759
原创 SOLID 原则
单一功能原则(Single responsibility principle)规定每个类都应该有一个单一的功能,并且该功能应该由这个类完全封装起来。所有它的(这个类的)服务都应该严密的和该功能平行(功能平行,意味着没有依赖)。保持一个类专注于单一功能点上的一个重要的原因是,它会使得类更加的健壮。
2024-09-13 20:41:28 328
原创 go最佳实践:如何舒适地编码
want bool}{},},},},})首先,我声明了测试目标。根据情况,它可以在每个测试案例里面。接下来,我定义了测试用例。我在这里使用了map,所以我可以使用测试名称作为map键。测试用例结构包含每个情况下的输入和预期输出。最后,我对测试用例进行了循环,并对每个测试用例运行了子测试。断言与之前的例子相同,但这里我从测试用例结构中获取输入和预期值。以表格驱动方式编写的测试很紧凑,重复性较低,如果你想添加更多的测试,你只需要添加一个新的测试用例,无需更多的断言。
2024-09-12 20:28:22 1042
原创 go 语言优雅地处理 error
我看到很多 golang 社区的开发者,特别是因为它的简单性而被吸引的开发者,对 golang 中的事情应该如何处理做出了一些快速的判断。其中一件事就是错误处理。由于目前大多数语言的开发者都来自于 OOP 背景,他们习惯于处理异常,或者说"抛出"异常的概念来停止当前的应用程序的流程,而且他们大多认为这也是 golang 的方式,我们必须在出错的情况下停止我们的应用程序的流程。他们错了!
2024-09-12 20:27:23 338
原创 go 语言常见问题(4)
方法的声明和函数类似,他们的区别是:方法在定义的时候,会在func和方法名之间增加一个参数,这个参数就是接收者,这样我们定义的这个方法就和接收者绑定在了一起,称之为这个接收者的方法。如果我们使用一个指针作为接收者,那么就会其作用了,因为指针接收者传递的是一个指向原值指针的副本,指针的副本,指向的还是原来类型的值,所以修改时,同时也会影响原来类型变量的值。使用值类型接收者定义的方法,在调用的时候,使用的其实是值接收者的一个副本,所以对该值的任何操作,不会影响原来的类型变量。可以变参数,可以是任意多个。
2024-09-10 20:35:56 1454
原创 go 语言常见问题(3)
for 循环支持 continue 和 break 来控制循环,但是它提供了一个更高级的break,可以选择中断哪一个循环 for 循环不支持以逗号为间隔的多个赋值语句,必须使用平行赋值的方式来初始化多个变量。
2024-09-10 20:34:48 336
原创 go 语言常见问题(2)
无,recover 必须在 defer 函数中运行。recover 捕获的是祖父级调用时的异常,直接调用时无效。直接 defer 调用也是无效。defer 调用时多层嵌套依然无效。必须在 defer 函数中直接调用才有效。
2024-09-09 21:10:43 562
翻译 go 语言垃圾回收
垃圾回收是释放掉那些不再被使用的内存空间的过程。换句话说,垃圾回收器会去检查哪些对象超出范围并且不会再被引用到,然后它回去释放掉那些对象占用的内存空间。这个过程实在 go 程序运行中以并发的方式去进行的,不是 go 程序执行之前,也不是 go 程序执行之后。go 垃圾回收器实现的说明文档给出了如下声明(runtime 包下的 mgc.go):垃圾回收是和go线程同时运行的,它是类型精确的,而且多个垃圾回收线程可以并行运行。它是一种使用了写屏障的并发标记清除的垃圾回收方式。它是非分代和非压缩的。
2024-09-08 22:09:31 137
原创 go 的内存布局和分配原理
根据内存管理(分配和回收)方式的不同,可以将内存分为 堆内存 和 栈内存。那么他们有什么区别呢?堆内存:由内存分配器和垃圾收集器负责回收栈内存:由编译器自动进行分配和释放一个程序运行过程中,也许会有多个栈内存,但肯定只会有一个堆内存。每个栈内存都是由线程或者协程独立占有,因此从栈中分配内存不需要加锁,并且栈内存在函数结束后会自动回收,性能相对堆内存要好。而堆内存呢?
2024-09-08 22:08:52 1005
原创 go 语言中的 iota
自增长常量经常包含一个自定义类型,允许你依靠编译器。const (如果一个函数以 int 作为它的参数而不是 Stereotype,如果你给它传递一个 Stereotype,它将在编译器期出现问题。const (// output:相反亦是成立的。给一个函数以 Stereotype 作为参数,你不能给它传递 int。const (!!1!return si := 2// output:这是一个戏剧性的转折,尽管如此。你可以传递一个数值常量,然后它能工作。
2024-09-07 22:09:13 396
原创 算法复杂度分析
我们都知道软件开发,数据结构、算法都是我们绕不过的知识点,而它们都是为了解决“快”和“省”的问题。所以我们怎么去衡量我们写出来的代码既快又省呢?这里就要用我们这篇文章说的两个复杂度来说明了。
2024-09-07 22:08:14 575
原创 go 切片长度与容量的区别
切片是一个结构体,保存着切片的容量,长度以及指向数组的指针(数组的地址)。从源码来看,当一个切片进行扩容时,会进行 growslice,这是一个花销较大的操作,在日常开发中,如果能明确知道切片的长度或者容量时,我们需要在初始化的时候声明,避免切片频繁扩容而带来的花销。
2024-09-06 21:00:05 387
原创 go 语言中的别名类型
当然了,这些类型必须在 Go 语言基本类型和高级类型的范畴之内。在它们当中,有一种被叫做 ”别名类型” 的类型。这条声明语句表示,stringAlias 是 string 类型的别名类型。顾名思义,别名类型与其源类型的区别恐怕只是在名称上,它们是完全相同的。从代码结果来看,stringAlias 以及 string 实际上就是同一种类型。
2024-09-06 20:59:07 217
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人