我很不清楚在哪种情况下我会想要使用值接收器而不是总是使用指针接收器.
要从文档中回顾一下:
type T struct {
    a int
}
func (tv  T) Mv(a int) int         { return 0 }  // value receiver
func (tp *T) Mp(f float32) float32 { return 1 }  // pointer receiver
该文档还表示"对于类型,如基本类型,切片和小结构,值接收机是非常便宜,所以,除非所述方法的语义需要一个指针,一个值是接收机有效和明确的."
首先它说它"非常便宜",但更问题的是它比指针接收器便宜.所以我做了一个小的基准测试(gist上的代码)向我展示了,即使对于只有一个字符串字段的结构,指针接收器也更快.这些是结果:
// Struct one empty string property
BenchmarkChangePointerReceiver  2000000000               0.36 ns/op
BenchmarkChangeItValueReceiver  500000000                3.62 ns/op
// Struct one zero int property
BenchmarkChangePointerReceiver  2000000000               0.36 ns/op
BenchmarkChangeItValueReceiver  2000000000               0.36 ns/op
(编辑:请注意第二点在较新的版本中无效,请参阅注释).
第二点它说,它是"高效和清晰",这更多的是品味问题,不是吗?就个人而言,我喜欢以任何方式使用相同的方式.效率在什么意义上?性能方面看来,指针几乎总是更有效率.使用一个int属性的少量测试运行显示Value接收器的最小优势(范围为0.01-0.1 ns/op)
有人能告诉我一个值接收器明显比指针接收器更有意义的情况吗?或者我在基准测试中做错了什么,我是否忽略了其他因素?
我收到一个接口,它基本上是一个切片。现在我想将它转换为指向切片的指针。问题是,我有切片本身或指向接口的指针。我可以在代码示例中轻松展示:
func main(){
    model := []int{1,2,3,4,5,6,7,8,10,11,133123123123}
    method(model)
}
func method(model interface{}){ 
    fmt.Println(reflect.TypeOf(model))    // this is of type []int
    fmt.Println(reflect.TypeOf(&model))   // this is of type *interface{}
}
我需要的是这种类型:
fmt.Println(reflect.TypeOf(result))    // this should be type *[]int
我只在运行时知道类型,因此我不能只接受
    &(model.([]int))
有没有办法使用 golang 反射来接收这个?'int' 类型在这里实际上并不重要,重要的是,它是一个指向 slice的指针。*[]interface{}也没关系。
编辑:
为了使问题更清楚,我应该补充说:我对切片的数据不感兴趣,而只对获取指向相同类型切片的指针(基本上可以为空)感兴趣。因此,James Henstridge 的回答非常有效。
我创建了一个proxy-camel,它接受SOAP(通过HTTP)和RESTful请求,并将它们转发到正确的Web服务.Camel不知道消息结构,它不知道WSDL或任何东西,它根据http头只知道它是否是SOAP.没有CXF端点.
此外,它做了一些处理.例外情况可能发生在那里,例如,当找不到服务或网址无效时.有没有一种简单的方法可以直接从这个驼峰返回有效的SOAPFault?我试着编写一个名为onException的简单处理器.它看起来像这样:
.choice().when().header("SOAP").processRef(ExceptionToSoapProcessor())
应该将任何Exception转换为SOAPFault的处理器如下所示
@Override
public void process(Exchange exchange) throws Exception {
    Exception exception = (Exception) exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
    Integer responseCode = (Integer) exchange.getOut().getHeader(Exchange.HTTP_RESPONSE_CODE);
    QName qName = SoapFault.FAULT_CODE_SERVER;
    if (responseCode != null && responseCode < 500) {
        qName = SoapFault.FAULT_CODE_CLIENT;
    }
    SoapFault fault = new SoapFault(exception.getMessage(), qName);
    Message outMessage = exchange.getOut();
    outMessage.setHeader(Message.RESPONSE_CODE, 500);
    outMessage.setFault(true);
    outMessage.setBody(fault);
    exchange.setException(null);
    exchange.removeProperty(Exchange.EXCEPTION_CAUGHT);
    exchange.setProperty(Exchange.EXCEPTION_HANDLED, true);
}
但现在我不明白我将如何编组它,响应看起来像这样:
org.apache.cxf.binding.soap.SoapFault: Unauthorized
("未经授权"是实际消息)
PS:之前我使用过dataformat SOAP,但如上所述,我在这个Camel中没有任何ServiceInterface.
go ×2
apache-camel ×1
function ×1
java ×1
pointers ×1
reflection ×1
slice ×1
soap ×1
soapfault ×1
web-services ×1