错题本一:方法接收者如何接收包外的结构体变量?

起因:在看Gin-vue-admin框架源码的时候,发现config/zap.go下竟然有两个方法

ZapEncodeLevelTransportLevel 
// ZapEncodeLevel 根据 EncodeLevel 返回 zapcore.LevelEncoder
// Author [SliverHorn](https://github.com/SliverHorn)
func (z *Zap) ZapEncodeLevel() zapcore.LevelEncoder {
	switch {
	case z.EncodeLevel == "LowercaseLevelEncoder": // 小写编码器(默认)
		return zapcore.LowercaseLevelEncoder
	case z.EncodeLevel == "LowercaseColorLevelEncoder": // 小写编码器带颜色
		return zapcore.LowercaseColorLevelEncoder
	case z.EncodeLevel == "CapitalLevelEncoder": // 大写编码器
		return zapcore.CapitalLevelEncoder
	case z.EncodeLevel == "CapitalColorLevelEncoder": // 大写编码器带颜色
		return zapcore.CapitalColorLevelEncoder
	default:
		return zapcore.LowercaseLevelEncoder
	}
}
// TransportLevel 根据字符串转化为 zapcore.Level
// Author [SliverHorn](https://github.com/SliverHorn)
func (z *Zap) TransportLevel() zapcore.Level {
	z.Level = strings.ToLower(z.Level)
	switch z.Level {
	case "debug":
		return zapcore.DebugLevel
	case "info":
		return zapcore.InfoLevel
	case "warn":
		return zapcore.WarnLevel
	case "error":
		return zapcore.WarnLevel
	case "dpanic":
		return zapcore.DPanicLevel
	case "panic":
		return zapcore.PanicLevel
	case "fatal":
		return zapcore.FatalLevel
	default:
		return zapcore.DebugLevel
	}
}
在简单了解了这两个方法的作用后

去查看了一下谁在调用,发现调用者是/core/internal/zap.go中的代码,这里就不放代码了

我看了之后很变扭,因为config作为配置包,为什么config/zap文件下会有初始化时用到的部分逻辑方法,还只是部分,不是全部。就好像将礼盒里的一整个蛋糕切出来一块,拿出来放到盒子上,一起交给寿星。

强迫症瞬间犯了

我想将这两个方法从config/zap.go中摘出来,也放到/core/internal/zap.go中

但是我发现就,这两个方法都是config/zap.go中Zap结构体的方法接收者

//config/zap.go中的结构体
type Zap struct {
	Level         string `mapstructure:"level" json:"level" yaml:"level"`                            // 级别
	Prefix        string `mapstructure:"prefix" json:"prefix" yaml:"prefix"`                         // 日志前缀
	Format        string `mapstructure:"format" json:"format" yaml:"format"`                         // 输出
	Director      string `mapstructure:"director" json:"director"  yaml:"director"`                  // 日志文件夹
	EncodeLevel   string `mapstructure:"encode-level" json:"encode-level" yaml:"encode-level"`       // 编码级
	StacktraceKey string `mapstructure:"stacktrace-key" json:"stacktrace-key" yaml:"stacktrace-key"` // 栈名

	MaxAge       int  `mapstructure:"mintage" json:"max-age" yaml:"max-age"`                      // 日志留存时间
	ShowLine     bool `mapstructure:"show-line" json:"show-line" yaml:"show-line"`                // 显示行
	LogInConsole bool `mapstructure:"log-in-console" json:"log-in-console" yaml:"log-in-console"` // 输出控制台
}

若是直接将其抽出来,会报错。

那么现在问题就抽象为:方法接收者如何接收包外的结构体变量?

       我模拟了一个简单的场景:现在有如下结构

├── a
│   └── a.go
├── b
│   └── b.go

有包a和包b,其中有a/b.go文件,a文件内容如下

package a
var AA = new (A)
type A struct {}

 那么b中的内容,按照直觉应该是这么写的

package b
import "test/a"
func (*A)b()  {}
func (*a.A)b()  {}
func (*AA)b()  {}

很抱歉,这样三种写法很明显都是错误的

那么你们能想到什么办法去实现这样的操作呢?

我的想法:

因为我是Java转Go,所以我想到Go和Java类比,Java确实不能在类外面去定义函数。

但继承是否可以,我们通过父类去调用子类的方法

package a
var AA = new (A)
type A struct {}
func (*A)AAA()  {

}
package b
import "RestFul/test/a"
type B struct {
	*a.A
}
func (*B)b()  {
	B.AAA("")
}

可以发现,当B中嵌入了匿名A也就是B继承了A后,我们自然可以实现接收B结构体,并使用其中的变量或方法

将这个思路使用到GVA框架中:

 将代码粘过来,不再报错

 

拓展:通过刚刚的模拟,我又产生了一些疑问

如下,1.这三种调用方法在底层的顺序上,逻辑上,有什么区别?

2.为什么编译器提示我2 ,3 方法必须要有一个参数??(这点我最不理解)

欢迎各位大佬在评论区指点,永远保持学习的心态

package b
import "RestFul/test/a"
type B struct {
	*a.A
}	
func (*B)b()  {
	a.AA.AAA()
	a.A.AAA("")
	B.AAA("")
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值