假设要构造 testStruct 这个结构体, 常规方法是写一个 func NewStruct() testStruct
函数
这里的方法是 将这个函数 改写成结构体方法 func (s *testStruct) New() *testStruct
比较一下使用时的不同:
_ = NewStruct()
_ = (&testStruct{}).New()
可以发现 New 这个函数被约束到了 testStruct 命名空间下, 这也是我的主要目的
基准测试中, 两种方式的执行效率几乎一致,当 struct 很大时, (&testStruct{}).New()
略有优势
package main
import (
"testing"
)
type testStruct struct {
value int
}
// 三种构造结构体的方法
func NewStruct() *testStruct { // 逃逸
return &testStruct{}
}
func NewStruct2() testStruct { // 不逃逸 但传值时发生拷贝
return testStruct{}
}
func (s *testStruct) New() *testStruct {
// 不逃逸,只拷贝了指针
// 更重要的是收束到了 testStruct 这个命名空间里
return s
}
func TestNew(t *testing.T){
_ = (&testStruct{}).New()
//fmt.Println(s)
}
func BenchmarkNew(b *testing.B){
for i := 0;i<b.N;i++{
_ = (&testStruct{}).New()
}
}
func BenchmarkNew2(b *testing.B){
for i := 0;i<b.N;i++{
_ = NewStruct()
}
}
1
vincentxue 2020-12-24 08:16:42 +08:00 1
这种写法是受了 OO 思想的影响,最好还是不要用 OO 的思想去写 Go 。
|
2
sxfscool 2020-12-24 08:49:19 +08:00
有啥用?
|
3
siteshen 2020-12-24 09:25:44 +08:00 1
「构造函数」的本质是「无中生有」,第三种是「有中生有」,不配称作「构造函数」。
func (s *testStruct) New() *testStruct |
4
sthwrong 2020-12-24 10:42:28 +08:00 1
都已经有了&testStruct{}, 为啥还要 New 一个?
|
6
reus 2020-12-26 16:41:39 +08:00 via Android 1
你这是初始化,并不是分配,所以应该叫 Init,不叫 New
|
7
UnknownDomain 2020-12-27 17:24:13 +08:00 1
可以无限的 New 下去
(&testStruct{}).New().New().New() |