Interface values are comparable. Two interface values are equal if they have identical dynamic types and equal dynamic values or if both have value nil.
var err error
var reader io.Reader
据了解,err 和reader 具有不同的动态类型(error 和io.Reader)因此没有可比性。
fmt.Println(err == reader)
会导致编译错误:
invalid operation: err == reader (mismatched types error and io.Reader)
如果为真,为什么 Println 命令对两个变量输出相同的结果?为什么两者都是 nil?
fmt.Printf("reader: %T", reader) // nil
fmt.Printf("error: %T", err) // nil
EDIT reflect.TypeOf(err) 或 reflect.TypeOf(reader) 也将输出 nil。我不明白如果类型不同,为什么输出相同。
最佳答案
接口(interface)值确实是可以比较的,但你只能比较可相互赋值的值(更准确地说,一个是可赋值给另一个的)。引自 Spec: Comparison operators:
In any comparison, the first operand must be assignable to the type of the second operand, or vice versa.
您不能将 error 值分配给 io.Reader,也不能将 io.Reader 值分配给一个错误,所以你不能比较它们。
它们可能存储也可能不存储相同的动态值,如果您想比较它们,首先将两者都隐藏到 interface{},这样您就可以比较它们,例如:
fmt.Println(interface{}(err) == interface{}(reader))
这将输出(在 Go Playground 上尝试):
true
注意:实际上只将其中一个转换为 interface{} 就足够了,因为那样的话,另一个值将与您转换为 的值的类型相当interface{}(任何值都可以转换为 interface{}),所以它也足以做到:
fmt.Println(interface{}(err) == reader)
测试与非nil 接口(interface)值的比较:
type x int
func (x) Error() string { return "" }
func (x) Read([]byte) (int, error) { return 0, nil }
err = x(0)
reader = x(0)
fmt.Println(interface{}(err) == interface{}(reader))
reader = x(1)
fmt.Println(interface{}(err) == interface{}(reader))
现在输出将是(在 Go Playground 上尝试):
true
false
另外不要忘记 nil 接口(interface)值不等于非 nil 接口(interface)值持有 nil 动态值。有关详细信息,请参阅 Hiding nil values, understanding why golang fails here
编辑:
fmt package 打印接口(interface)内的值,而不是接口(interface)值。引用自 fmt 的包文档:
Regardless of the verb, if an operand is an interface value, the internal concrete value is used, not the interface itself.
同样适用于 reflect.TypeOf() : 它返回动态类型,但是如果你传递一个 nil 接口(interface)值给它,它返回 nil 所以 fmt 包将打印 无。引用其文档:
TypeOf returns the reflection Type that represents the dynamic type of i. If i is a nil interface value, TypeOf returns nil.
关于go - Golang中空接口(interface)的比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54003271/
我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。
1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,
方法应返回-1,0或1分别表示“小于”、“等于”和“大于”。对于某些类型的可排序对象,通常将排序顺序基于多个属性。以下是可行的,但我认为它看起来很笨拙:classLeagueStatsattr_accessor:points,:goal_diffdefinitializepts,gd@points=pts@goal_diff=gdenddefothercompare_pts=pointsother.pointsreturncompare_ptsunlesscompare_pts==0goal_diffother.goal_diffendend尝试一下:[LeagueStats.new(
我有两个文本文件,master.txt和926.txt。如果926.txt中有一行不在master.txt中,我想写入一个新文件notinbook.txt。我写了我能想到的最好的东西,但考虑到我是一个糟糕的/新手程序员,它失败了。这是我的东西g=File.new("notinbook.txt","w")File.open("926.txt","r")do|f|while(line=f.gets)x=line.chompifFile.open("master.txt","w")do|h|endwhile(line=h.gets)ifline.chomp!=xputslineendende
我正在尝试对某些帖子的评论使用简单的身份验证。用户使用即时ID和密码输入评论我使用“bcrypt”gem将密码存储在数据库中。在comments_controller.rb中像这样@comment=Comment.new(comment_params)bcrypted_pwd=BCrypt::Password.create(@comment.user_pwd)@comment.user_pwd=bcrypted_pwd当用户想要删除他们的评论时,我使用data-confirm-modalgem来确认数据在这部分,我必须解密用户输入的密码以与数据库中的加密密码进行比较我怎样才能解密密码,
我正在运行这样的代码:ifvalid_from>Date.today当我运行它时,我得到一个错误提示comparisonofDatewithnilfailed我假设它正在发生,因为在某些情况下valid_from是nil。有没有办法避免出现此错误? 最佳答案 你可以这样做:ifvalid_fromandvalid_from>Date.today...end这将在第一个子句上短路,因为valid_from为nil,因此为false。 关于ruby-Date与nil的比较失败-ruby,我们
在Railcasts上,我注意到一个非常有趣的功能“转到符号”窗口。它像Command-T一样工作,但显示当前文件中可用的类和方法。如何在vim中获取它? 最佳答案 尝试:helptags有各种程序和脚本可以生成标记文件。此外,标记文件格式非常简单,因此很容易将sed(1)或类似的脚本组合在一起,无论您使用何种语言,它们都可以生成标记文件。轻松获取标记文件(除了下载生成器之外)的关键在于格式化样式而不是实际解析语法。 关于ruby-on-rails-Textmate'Gotosymbol
以下测试中的第3个失败:specify{(0.6*2).shouldeql(1.2)}specify{(0.3*3).shouldeql(0.3*3)}specify{(0.3*3).shouldeql(0.9)}#thisonefails这是为什么呢?这是浮点问题还是ruby或rspec问题? 最佳答案 从rspec-2.1开始specify{(0.6*2).shouldbe_within(0.01).of(1.2)}在那之前:specify{(0.6*2).shouldbe_close(1.2,0.01)}
有没有简单的方法(即使用宇宙飞船运算符)在Ruby中定义基于两个不同属性的比较?IE。如果我有一个包含两个属性attr1和attr2的类,是否有Rubyesque方法在attr1上比较此类的两个实例,如果它们相等,则在attr2上比较它们? 最佳答案 这是一种易于扩展(扩展到更多属性)的方式:def(other)[self.attr1,self.attr2][other.attr1,other.attr2]end 关于Ruby-使用Comparablemixin比较两个不同属性的对象,我
ruby1.9.3dev(2011-09-23修订版33323)[i686-linux]轨道3.0.20最近为什么在与DateTimeonRails相关的RSpecs项目上工作我发现在给定日期以下语句发出的值date.end_of_day.to_datetime和date.to_datetime.end_of_day虽然它们表示相同的日期时间,但比较时返回false。为了确认这一点,我打开了Rails控制台并尝试了以下操作1.9.3dev:053>monday=Time.now.monday=>2013-02-2500:00:00+05301.9.3dev:054>monday.cla