使用下面的代码,如果没有给出文件参数,第 9 行会引发 panic panic: runtime error: index out of range 符合预期。
当直接将导致 panic 的东西(os.Args[1])传递给它时,我如何“捕捉”这种 panic 并处理它?很像 PHP 中的 try/catch 或 Python 中的 try/except。
我在 StackOverflow 上进行了搜索,但没有找到任何可以回答此问题的内容。
package main
import (
"fmt"
"os"
)
func main() {
file, err := os.Open(os.Args[1])
if err != nil {
fmt.Println("Could not open file")
}
fmt.Printf("%s", file)
}
最佳答案
panic 的程序可以recover使用内置 recover() 函数:
The
recoverfunction allows a program to manage behavior of a panicking goroutine. Suppose a functionGdefers a functionDthat callsrecoverand a panic occurs in a function on the same goroutine in whichGis executing. When the running of deferred functions reachesD, the return value ofD's call torecoverwill be the value passed to the call ofpanic. IfDreturns normally, without starting a newpanic, the panicking sequence stops. In that case, the state of functions called betweenGand the call topanicis discarded, and normal execution resumes. Any functions deferred byGbeforeDare then run andG's execution terminates by returning to its caller.The return value of recover is nil if any of the following conditions holds:
panic's argument wasnil;- the goroutine is not panicking;
recoverwas not called directly by a deferred function.
这是一个如何使用它的示例:
// access buf[i] and return an error if that fails.
func PanicExample(buf []int, i int) (x int, err error) {
defer func() {
// recover from panic if one occured. Set err to nil otherwise.
if (recover() != nil) {
err = errors.New("array index out of bounds")
}
}()
x = buf[i]
}
请注意, panic 往往不是正确的解决方案。 Go 范式是显式检查错误。只有在正常程序执行期间没有发生 panic 的情况下,程序才应该 panic 。例如,无法打开文件是可能发生的事情,不应该引起 panic ,而内存不足值得 panic 。然而,这种机制的存在是为了能够捕捉到这些情况,并可能优雅地关闭。
关于exception-handling - 在 Golang 中捕捉 panic ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25025467/
我在思考流量控制的最佳实践。我应该走哪条路?1)不要检查任何东西并让程序失败(更清晰的代码,自然的错误消息):defself.fetch(feed_id)feed=Feed.find(feed_id)feed.fetchend2)通过返回nil静默失败(但是,“CleanCode”说,你永远不应该返回null):defself.fetch(feed_id)returnunlessfeed_idfeed=Feed.find(feed_id)returnunlessfeedfeed.fetchend3)抛出异常(因为不按id查找feed是异常的):defself.fetch(feed_id
抱歉,如果问题很明显,我才刚刚开始使用Rails。我现在在几个Controller方法中有以下代码:respond_todo|format|if@project.saveformat.html{redirect_to(edit_project_url(@project),:notice=>'#{user.name}addedto#{role}.')}format.jselseformat.html{render:action=>"edit"}format.js#...endend那么问题来了,对于所有方法中的错误,最好的方法是什么?是否建议我使用save!并在rescue_action
在ruby中,begin#...rescue#...end不会捕获不是StandardError子类的异常。在C中,rb_rescue(x,Qnil,y,Qnil);VALUEx(void){/*...*/returnQnil;}VALUEy(void){/*...*/returnQnil;}会做同样的事情。我如何从rubyC扩展中rescueException=>e(而不仅仅是rescue=>e)? 最佳答案 Ruby需要更多文档。我不得不进入ruby源代码,这是我发现的:VALUErb_rescue(VALUE(*b_p
我正在从rails2.3迁移到rails3.1,我试图在生成异常时发送电子邮件。我正在使用exception_notificationgem。我的其余电子邮件都在工作。但是异常邮件不会被解雇。以下是我的staging.rb文件中的设置。config.action_mailer.perform_deliveries=trueconfig.action_mailer.raise_delivery_errors=true下面是application.rb中的代码C::Application.config.middleware.useExceptionNotification::Rack,:e
我正在使用Rails4.0。我正在发送这样的事件(注意:remote=>true):true,:class=>"rate-btnyes-btnbtnbtn-defaultbtn-sm"}%>我的Controller看起来像这样:defratevideo=Video.find_by(hashed_id:params[:id])action=params[:yesno]putsvideo.hashed_idputsactionrespond_todo|format|if(action=='yes')new_rating=video.rating==1?0:1video.update(is_
函数是:defcreateuser(name,pass,time)putsname,pass,timeend我试试:handle_asynchronously:createuser("a","b","c")得到一个错误:语法错误,意外'(',期待keyword_end谢谢。===编辑===日本的用户数据库和北京的网络服务器。所以我用这种方式来创建用户。defcreateuser(name,pass,time)Net::HTTP.get(URI.parse("http://www.example.net/builduser.php?hao=#{name}&mi=#{pass}&da=#{
我在做:can:manage,:allifuser.role=='admin'can:approve,Anunciodo|anuncio|anuncio.try(:aprovado)==falseend我的第二种方法不起作用,因为:manage:all覆盖了它。有一种方法可以声明可以管理除批准之外的所有内容吗?在里面批准我只是做can:approve,Anunciodo|anuncio|user.role=='admin'&&anuncio.try(:aprovado)==falseend什么是更好的解决方案? 最佳答案 尝试换一种
如果尝试批量分配attr_accessible不允许的属性,是否有办法让Rails引发错误?这在开发中会很方便,可以提醒我为什么我Shiny的新模型不起作用,也有助于登录生产环境以检测恶意事件。我正在使用Rails2.3.8,但可能很快就会迁移到3。 最佳答案 从Rails3.2开始,这不再需要monkeypatching——rails现在提供了这种行为。将其放入development.rb和test.rb:config.active_record.mass_assignment_sanitizer=:strict
我有一个RubyonRails应用程序,其中一个模型的验证失败。对于此验证可能失败的地方,代码库有不同的入口点。我有兴趣弄清楚它是从哪里来的。由于这是一个简单的验证方法,因此不涉及任何异常,我只是从方法中返回false并且保存失败。目前是否还可以记录回溯以查明此验证源自哪个服务/路由,以便我可以查看是什么导致此对象的状态发生更改以使其验证失败? 最佳答案 你可以试试caller():deffoo2putscallerenddeffoofoo2#line5endfoo#line7结果:test.rb:5:in`foo'test.rb:
乍一看,我以为新的ruby2.0Thread.handle_interrupt会解决我所有的异步中断问题,但除非我弄错了,否则我无法让它做我想做的事(我的问题在最后和标题中)。从文档中,我可以看到如何避免在某个block中接收中断,将它们推迟到另一个block。这是一个示例程序:duration=ARGV.shift.to_it=Thread.newdoThread.handle_interrupt(RuntimeError=>:never)do5.times{putc'-';sleep1}Thread.handle_interrupt(RuntimeError=>:immedia