Go方法调用简写规范的适用性 [英] Go method call shorthand spec applicability

查看:129
本文介绍了Go方法调用简写规范的适用性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从Go规范的 Calls 部分: https:// golang。 org / ref / spec#Calls



lockquote

方法调用 xm() x (的类型)的方法集包含 m 并且可以分配参数列表,则c>到 m 的参数列表。如果 x 是可寻址的,并且& x 的方法集包含 m xm()(& x).m()

$的缩写b $ b

我的程序。

  package main 

进口(
fmt


func main(){
p:=点{2,3}

p.FakeScale(10)
fmt.Println(p)

p.RealScale(10)
fmt.Println(p)
}

类型Point结构{
x int
y int
}

func(p Point)FakeScale(s int){
px * = s
py * = s
}

func(p * Point)RealScale(s int){
px * = s
py * = s
}

以下是输出。

  {2,3} 
{20,30}

我的问题是关于这部分规范的具体内容。


$ b


如果 x 是可寻址的,& x 的方法d集包含 m xm()(& x).m的简写()


我的问题。


  1. 引用部分是否适用于 p.FakeScale(10)?我的猜测是否,因为虽然 p 是可寻址的,但是& p 的方法集不包含 FakeScale p 的方法集包含 FakeScale ,因为它使用值接收器,但 p 的方法集不包含 FakeScale ,因此这部分规范不适用于 p.FakeScale(10) code>。我是否正确?

  2. 引用部分是否适用于 p.RealScale(10)?我的猜测是是,因为 p 是可寻址的,& p 的方法集包含 RealScale 凭借它使用指针接收器。因此,这部分规范适用于 p.RealScale(10)。我是否正确?

  3. 您可以提供一个示例代码,其中 xm()有效,但 x 不可寻址,因此这部分规范不适用?


解决方案

不幸的是,语言律师必须阅读整个规范才能在上下文中放置一个句子: Go编程语言规范


方法集



一个类型可能有一个与之关联的方法集。
接口类型的方法集是它的接口。任何其他类型T
的方法集由所有使用接收方类型T声明的方法组成。相应的指针类型* T的方法集
是接收方声明的所有方法
的集合* T或T(即它也包含T的方法
)。其他规则适用于包含匿名字段的结构
,如结构类型部分所述。任何其他类型都有一个
空方法集。在一个方法集合中,每个方法必须有一个唯一的
非空白方法名称。



类型的方法集合决定类型
实现以及可以使用该
类型的接收方调用的方法。



调用



如果方法集合(类型) x
包含m,参数列表可以分配给m的参数列表
。如果x是可寻址的并且& x的方法集包含m,则xm()是
(& x).m()的简写。 href =https://golang.org/ref/spec#Address_operators =nofollow noreferrer>地址运算符



对于操作数x类型T,地址操作& x产生类型为* T的
指针给x。操作数必须是可寻址的,即
要么是变量,指针间接寻址,要么是分片索引操作;
或可寻址结构操作数的字段选择器;或可寻址数组的数组
索引操作。作为
可寻址性要求的一个例外,x也可以是一个(可能加了括号的)
复合字面值。







例如,

 包主

导入(
fmt


类型Point结构{
x int
y int
}

func( P点)FakeScale(s int){
px * = s
py * = s
}

func(p * Point)RealScale(s int){
px * = s
py * = s
}

func main(){
p:= Point {2,3}

p.FakeScale(10)
fmt.Println(p)

p.RealScale(10)
fmt.Println(p)
}

Point类型的方法集合由接收器类型Point(FakeScale)声明的所有方法组成。



方法调用p.FakeScale是有效的,因为p(Point)的类型的方法集包含FakeScale,参数列表(10)可以分配给paramete r列表,(int),FakeScale。



类型* Point的方法集合由接收器类型* Point(RealScale)声明的所有方法组成。

因为p是可寻址的(p是一个变量)并且& p的方法集包含RealScale,所以p.RealScale()是(& p).RealScale()的简写形式。






另请参阅我对以前问题的回答:如何用类型断言后的指针接收器?


From the Calls section of Go spec: https://golang.org/ref/spec#Calls

A method call x.m() is valid if the method set of (the type of) x contains m and the argument list can be assigned to the parameter list of m. If x is addressable and &x's method set contains m, x.m() is shorthand for (&x).m()

My program.

package main

import (
    "fmt"
)

func main() {
    p := Point{2, 3}

    p.FakeScale(10)
    fmt.Println(p)

    p.RealScale(10)
    fmt.Println(p)
}

type Point struct {
    x int
    y int
}

func (p Point) FakeScale(s int) {
    p.x *= s
    p.y *= s
}

func (p *Point) RealScale(s int) {
    p.x *= s
    p.y *= s
}

Here is the output.

{2, 3}
{20, 30}

My question is specifically about this part of the spec.

If x is addressable and &x's method set contains m, x.m() is shorthand for (&x).m()

My questions.

  1. Is the quoted part applicable to p.FakeScale(10)? My guess is "No" because although p is addressable, &p's method set does not contain FakeScale. p's method set contains FakeScale because it uses value receiver, but p's method set does not contain FakeScale, therefore this part of the spec is not applicable to p.FakeScale(10). Am I correct?
  2. Is the quoted part applicable to p.RealScale(10)? My guess is "Yes" because p is addressable and &p's method set contains RealScale by virtue of it using a pointer receiver. Therefore, this part of the spec is applicable to p.RealScale(10). Am I correct?
  3. Can you provide an example code where x.m() is valid but x is not addressable, and thus this part of the spec is not applicable?

解决方案

Unfortunately, language lawyers have to read the entire specification to put a single sentence in context: The Go Programming Language Specification.

Method sets

A type may have a method set associated with it. The method set of an interface type is its interface. The method set of any other type T consists of all methods declared with receiver type T. The method set of the corresponding pointer type *T is the set of all methods declared with receiver *T or T (that is, it also contains the method set of T). Further rules apply to structs containing anonymous fields, as described in the section on struct types. Any other type has an empty method set. In a method set, each method must have a unique non-blank method name.

The method set of a type determines the interfaces that the type implements and the methods that can be called using a receiver of that type.

Calls

A method call x.m() is valid if the method set of (the type of) x contains m and the argument list can be assigned to the parameter list of m. If x is addressable and &x's method set contains m, x.m() is shorthand for (&x).m().

Address operators

For an operand x of type T, the address operation &x generates a pointer of type *T to x. The operand must be addressable, that is, either a variable, pointer indirection, or slice indexing operation; or a field selector of an addressable struct operand; or an array indexing operation of an addressable array. As an exception to the addressability requirement, x may also be a (possibly parenthesized) composite literal.


For example,

package main

import (
    "fmt"
)

type Point struct {
    x int
    y int
}

func (p Point) FakeScale(s int) {
    p.x *= s
    p.y *= s
}

func (p *Point) RealScale(s int) {
    p.x *= s
    p.y *= s
}

func main() {
    p := Point{2, 3}

    p.FakeScale(10)
    fmt.Println(p)

    p.RealScale(10)
    fmt.Println(p)
}

The method set of type Point consists of all methods declared with receiver type Point (FakeScale).

A method call p.FakeScale is valid since the method set of (the type of) p (Point) contains FakeScale and the argument list, (10), can be assigned to the parameter list, (int), of FakeScale.

The method set of type *Point consists of all methods declared with receiver type *Point (RealScale).

Since p is addressable (p is a variable) and &p's method set contains RealScale, p.RealScale() is shorthand for (&p).RealScale().


Also, see my answer to your earlier question: How to invoke a method with pointer receiver after type assertion?.

这篇关于Go方法调用简写规范的适用性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆