我对 this bit of code from the HTTP package 感到困惑:
type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
为什么 ServeHTTP 方法具有与其类型完全相同的签名 - 这有什么意义?
测试,我发现如果我传递一个随机函数(foo)给HandlerFunc:
var bar = HandlerFunc(foo)
bar 成为 HandlerFunc 的一个实例,foo 作为它的 ServeHTTP 方法。现在我真的很困惑这到底是怎么回事。
如果我在一个类型上有多个方法,我如何知道哪个方法将附加到新实例以及使用什么名称或顺序?
最佳答案
这种方法允许您在需要 Handler 的上下文中使用函数。
发生的事情是,有一个 Handler 接口(interface):
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
并且各种函数被声明为接受被声明为属于该接口(interface)的参数——例如:
func TimeoutHandler(h Handler, ns int64, msg string) Handler {
f := func() <-chan int64 {
return time.After(ns)
}
return &timeoutHandler{h, f, msg}
}
这意味着当你调用这样一个函数时,你必须传入一个属于满足这个接口(interface)的类型的对象,也就是说,一个具有ServeHTTP 具有适当签名的方法。 (在 Go 中,与某些语言不同,类型不需要显式实现接口(interface),它只需要具有接口(interface)指定的方法即可。)
因此,您引用的代码片段:
type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
创建一个基于 func(ResponseWriter, *Request) 的 HandlerFunc 类型,但是使用名为 ServeHTTP 的方法扩充该类型适当的签名,使其满足 Handler 接口(interface)。此 ServeHTTP 方法只是调用函数本身。所以,如果 f 是一个具有正确签名的函数,你可以这样写:
var h HandlerFunc = f // h == f, but converted to a HandlerFunc
// so it satisfies the Handler interface.
TimeoutHandler(h, 1000000, "timed out")
澄清一些关于此的事情:
Testing, I discovered that if I pass a random function (
foo) to theHandlerFunc:var bar = HandlerFunc(foo)
barbecomes an instance ofHandlerFuncwithfooas itsServeHTTPmethod. Now I'm really confused about how on earth this works.
首先,更正确的说法是您已转换一个随机函数 foo 键入 HandlerFunc ,而不是你将函数传递给HandlerFunc,就像HandlerFunc是一个函数一样。 (HandlerFunc(foo) 表示法是类型转换;您也可以编写 var bar HandlerFunc = foo 并让转换隐式发生。)
其次,更正确的说法是 bar 有一个 ServeHTTP 方法 invokes foo,而不是foo 本身实际上是 ServeHTTP 方法。
这有意义吗?
关于function - 这个Go函数类型 "HandlerFunc"是怎么工作的,来自标准库 "net/http",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8690900/
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar
是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我可以得到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类的两个特殊实例的字符串
我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)
我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了