我不明白如何正确确保某些东西不是 nil在这种情况下:
package main
type shower interface {
getWater() []shower
}
type display struct {
SubDisplay *display
}
func (d display) getWater() []shower {
return []shower{display{}, d.SubDisplay}
}
func main() {
// SubDisplay will be initialized with null
s := display{}
// water := []shower{nil}
water := s.getWater()
for _, x := range water {
if x == nil {
panic("everything ok, nil found")
}
//first iteration display{} is not nil and will
//therefore work, on the second iteration
//x is nil, and getWater panics.
x.getWater()
}
}
nil 的唯一方法是通过使用反射。最佳答案
这里的问题是 shower是 interface类型。 Go 中的接口(interface)类型保存实际值及其动态类型。更多详情:The Laws of Reflection #The representation of an interface .
您返回的 slice 包含 2 个非 nil值。第二个值是一个接口(interface)值,一个 (value;type) 对,包含一个 nil指针值和 *display混凝土类型。引自 Go Language Specification: Comparison operators :
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.
nil 进行比较,它将是 false .如果将其与代表对 (nil;*display) 的接口(interface)值进行比较,它将是 true :if x == (*display)(nil) {
panic("everything ok, nil found")
}
这似乎不可行,因为您必须知道接口(interface)拥有的实际类型。但请注意,您可以使用反射来判断非 nil接口(interface)值包装了一个 nil值使用 Value.IsNil() .你可以在 Go Playground 上看到一个例子。 .interface只是一个方法集,如果相同的方法是 method set 的一部分,任何类型都会实现它类型的。有些类型不能是 nil ,例如 struct或自定义类型 int作为其基础类型。在这些情况下,您不需要能够存储 nil该特定类型的值。nil是一个有效值(例如 slice 、映射、 channel 、所有指针类型),因此为了在运行时存储满足接口(interface)的值,支持存储 nil 是合理的。界面里面。但除了nil在接口(interface)内部,我们必须将其动态类型存储为 nil value 不携带此类信息。另一种选择是使用 nil当其中存储的值为nil时作为接口(interface)值本身,但这种解决方案是不够的,因为它会丢失动态类型信息。Some people say that Go's interfaces are dynamically typed, but that is misleading. They are statically typed: a variable of interface type always has the same static type, and even though at run time the value stored in the interface variable may change type, that value will always satisfy the interface.
nil值 interface类型,使用显式 nil值,然后您可以测试 nil平等。最常见的例子是内置的 error type 是一种方法的接口(interface)。只要没有错误,就明确设置或返回值 nil而不是某些具体(非接口(interface))类型错误变量的值(这将是非常糟糕的做法,请参见下面的演示)。shower ) shower 类型的但具体类型*display输入 shower slice,将创建一个接口(interface)值,它是一对 (value;type) 其中 value 是 nil和类型是 *display .该对内的值将为 nil ,而不是接口(interface)值本身。如果你想放一个 nil值进入 slice ,那么接口(interface)值本身就是 nil和条件 x == nil将是 true .type MyErr string
func (m MyErr) Error() string {
return "big fail"
}
func doSomething(i int) error {
switch i {
default:
return nil // == nil
case 1:
var p *MyErr
return p // != nil
case 2:
return (*MyErr)(nil) // != nil
case 3:
var p *MyErr
return error(p) // != nil because the interface points to a
// nil item but is not nil itself.
case 4:
var err error // == nil: zero value is nil for the interface
return err // This will be true because err is already interface type
}
}
func main() {
for i := 0; i <= 4; i++ {
err := doSomething(i)
fmt.Println(i, err, err == nil)
}
}
输出:0 <nil> true
1 <nil> false
2 <nil> false
3 <nil> false
4 <nil> true
在情况 2 中 nil返回指针,但首先将其转换为接口(interface)类型( error ),因此会创建一个接口(interface)值,其中包含 nil值和类型 *MyErr ,所以接口(interface)值不是 nil .
关于pointers - 隐藏 nil 值,理解为什么 golang 在这里失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33619954/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput
我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?
似乎无法为此找到有效的答案。我正在阅读Rails教程的第10章第10.1.2节,但似乎无法使邮件程序预览正常工作。我发现处理错误的所有答案都与教程的不同部分相关,我假设我犯的错误正盯着我的脸。我已经完成并将教程中的代码复制/粘贴到相关文件中,但到目前为止,我还看不出我输入的内容与教程中的内容有什么区别。到目前为止,建议是在函数定义中添加或删除参数user,但这并没有解决问题。触发错误的url是http://localhost:3000/rails/mailers/user_mailer/account_activation.http://localhost:3000/rails/mai