关于type之后的类型作为case的一种情况的类型检查 发现出错

GuoYuefei · · 724 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

以下代码在类型检查那边会出错,只会执行default的。但是在简单的代码中我试验过了可以使用这种type之后的类型作为case的一种情况的 ```go type CBC func(b cipher.Block, iv []byte) cipher.BlockMode type CFB func(b cipher.Block, iv []byte) cipher.Stream type ModeFunc string const ( CBCDecrypter ModeFunc = "NewCBCDecrypter" CBCEncrypter ModeFunc = "NewCBCEncrypter" CFBDecrypter ModeFunc = "NewCFBDecrypter" CFBEncrypter ModeFunc = "NewCFBEncrypter" ) //接下来就是将这两种不同模式下的aes加密写成一个函数 func AESCrypt(word, key, iv []byte, modeFunc ModeFunc) []byte { CheckKey(key) funcs := map[ModeFunc] interface{} { CBCEncrypter: cipher.NewCBCEncrypter, CBCDecrypter: cipher.NewCBCDecrypter, CFBDecrypter: cipher.NewCFBDecrypter, CFBEncrypter: cipher.NewCFBEncrypter, } block, err := aes.NewCipher(key) if err != nil { panic(err) } //得先判定加密还是解密 if modeFunc == CBCEncrypter || modeFunc == CFBEncrypter { word = PKCS7Padding(word, block.BlockSize()) } result := make([]byte, len(word)) //bug 类型检查为什么会运行到default。。。 查到了。 //不用type类型的时候是可以识别的 但是为什么用type之后的别名识别不了呢 //查了下资料,资料显示 type和c/c++中的typedef是不一样的 //type之后产生的类型只继承了原有类型的所有元素 但是不包括函数 //所以两个类型是不对等的 其实有些奇怪为什么在上面函数中map的value类型为什么能直接使用type之后的类型而且不出问题 //而且事实上我在某个地方类型检查是使用过type类型,并没有出问题 switch fun := funcs[modeFunc].(type) { case CBC: blockMode := fun(block, iv) blockMode.CryptBlocks(result, word) case CFB: blockMode := fun(block, iv) blockMode.XORKeyStream(result, word) default: fmt.Println("something wrong!") } if modeFunc == CBCDecrypter || modeFunc == CFBDecrypter { result = PKCS7UnPadding(result) } return result } ``` 之前我用一个简单的文件检查过这种方法能实施的,但是到这里就出错了。必须要把函数原型原封不动的写出来才能正常执行。 switch改成这样才是正确的。但是我无法理解为什么上面的方式是不对的 ```go switch fun := funcs[modeFunc].(type) { case func(b cipher.Block, iv []byte) cipher.BlockMode: blockMode := fun(block, iv) blockMode.CryptBlocks(result, word) case func(b cipher.Block, iv []byte) cipher.Stream: blockMode := fun(block, iv) blockMode.XORKeyStream(result, word) default: fmt.Println("something wrong!") } ``` 还有以下代码也是成立的,证明map的value的类型使用type之后的类型也是可以的。 ```go func AESCBCCrypt(word, key, iv []byte, modeFunc ModeFunc) []byte { funcs := map[ModeFunc]NewCBCCipherModel{ CBCEncrypter: cipher.NewCBCEncrypter, CBCDecrypter: cipher.NewCBCDecrypter, } //检查key的合法性 CheckKey(key) block, err := aes.NewCipher(key) if err != nil { panic(err) } blockSize := block.BlockSize() //若处于加密模式,就先加补码否则在这就啥也不动 if modeFunc == CBCEncrypter { //加上补码确保word是aes.blockSize的整倍数 word = PKCS7Padding(word, blockSize) } blockMode := funcs[modeFunc](block, iv) result := make([]byte, len(word)) blockMode.CryptBlocks(result, word) //处于解码模式的时候 结果去补码 if modeFunc == CBCDecrypter { result = PKCS7UnPadding(result) } return result } ``` 我在这就搞不懂第一块代码的问题所在了,虽然能用第二种写法解决问题但是无法理解其中的错误。还望高手能够从细节方面给出简答。再次感谢!!!

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

724 次点击  
加入收藏 微博
3 回复  |  直到 2018-11-08 15:46:47
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传