2017-05-13 2 views
1

Aus dem Calls Abschnitt Go spec: https://golang.org/ref/spec#CallsGo Methodenaufruf Stenografie spec Anwendbarkeit

Ein Aufruf Methode x.m() gültig ist, wenn die Methode Satz (Art von) xm enthält und die Argumentliste kann der Parameterliste von m zugewiesen werden. Wenn x adressierbar und &x ‚s Methode Set enthält m ist x.m() Abkürzung für (&x).m()

Mein Programm.

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 
} 

Hier ist der Ausgang.

{2, 3} 
{20, 30} 

Meine Frage bezieht sich speziell auf diesen Teil der Spezifikation.

Wenn x adressierbar ist und &x ‚s Methode Set enthält m ist x.m() Abkürzung für (&x).m()

Meine Fragen.

  1. Ist der angegebene Teil auf p.FakeScale(10) anwendbar? Meine Schätzung ist "Nein", obwohl adressierbar ist, enthält &p 's Methodensatz nicht FakeScale. Der Methodensatz enthält FakeScale, da er den Wertempfänger verwendet, aber der Methodensatz enthält nicht FakeScale, daher ist dieser Teil der Spezifikation nicht auf p.FakeScale(10) anwendbar. Hab ich recht?
  2. Ist der angegebene Teil auf p.RealScale(10) anwendbar? Meine Vermutung ist "Ja", weil adressierbar ist und &p 's Methodensatz enthält RealScale aufgrund der Verwendung eines Zeigerempfängers. Daher ist dieser Teil der Spezifikation auf p.RealScale(10) anwendbar. Hab ich recht?
  3. Können Sie einen Beispielcode angeben, in dem x.m() gültig ist, aber x nicht adressierbar ist und dieser Teil der Spezifikation daher nicht anwendbar ist?

Antwort

-2

Hm. Auch ich fange an, meine Kenntnisse der englischen Sprache zu bezweifeln, aber ich werde versuchen zu antworten.

Sie zitieren 2 Sätze nach Spezifikation.

  1. Beschreibt Bedingungen für die Gültigkeit der Methode.
  2. Beschreibt Kurzschrift für Empfänger von Zeigertypen.

Zurück zu Ihrer Frage:

Sie 2 definiert Methoden für 2 Arten: erste - Empfänger von Punkt und dem zweiten - Empfänger von Zeiger-zu-Punkt.

Offensichtlich Stenografie Definition für Zeigertypen ist nicht anwendbar für Nicht-Zeiger-Typen.

Sie sind also in Ihren Fragen richtig 1 oder 2.

Und Ihre dritte Frage ist in der Tat der Frage 1: FakeScale gilt Methode aber Verfahren mit nicht-Zeigertyp in Empfänger, so Stenografie Definition ist nicht anwendbar.

+0

Das habe ich in meiner dritten Frage nicht gefragt. Ich fragte, ob Sie ein Beispiel für 'x.m()' geben können, wobei 'x' nicht adressierbar ist. In meinem Code ist "p" unabhängig davon, ob "p.FakeScale()" aufgerufen wird oder "p.RealScale()" aufgerufen wird. –

0

Leider Sprache Anwälte haben die gesamte Spezifikation lesen einen einzigen Satz in Zusammenhang zu bringen: The Go Programming Language Specification.

Method sets

A-Typ kann ein Verfahren mit Satz zugeordnet sein. Der Methodensatz eines Schnittstellentyps ist seine Schnittstelle. Verfahren Satz von jedem anderen Typ T besteht aus allen mit Empfängertyp deklarierten Methoden T. Das Verfahren des entsprechenden Zeigertypen gesetzt * T ist die Menge aller Methoden mit Empfänger erklärt * T oder T (das heißt, es auch enthält die Methode Satz von T). Weitere Regeln gelten für Strukturen, die anonyme Felder enthalten, , wie im Abschnitt über Strukturtypen beschrieben. Jeder andere Typ hat einen leeren Methodensatz. In einem Methodenset muss jede Methode einen eindeutigen nicht leeren Methodennamen haben.

Der Methodensatz eines Typs bestimmt die Schnittstellen, die der Typ implementiert und die Methoden, die mit einem Empfänger dieses Typs aufgerufen werden können.

Calls

Ein Methodenaufruf x.m() ist gültig, wenn der Satz von Verfahren (die Art von) x enthält m und die Argumentliste kann auf die Parameterliste von m zugeordnet werden. Wenn x adressierbar ist und x & Methode Set enthält m, x.m() ist eine Abkürzung für (& x) .m().

Address operators

für einen Operanden x vom Typ T, die Adressenoperation & x erzeugt einen Zeiger vom Typ T * x. Der Operand muss adressierbar sein, dh entweder eine Variable, eine Zeiger-Indirektion oder eine Schicht-Indexierungsoperation; oder ein Feldselektor eines adressierbaren Strukturoperanden; oder ein Array Indizierung Operation eines adressierbaren Array. Als Ausnahme von der Adressierbarkeitsanforderung kann x auch ein (möglicherweise geklammertes) zusammengesetztes Literal sein.


Zum Beispiel

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) 
} 

der Methode vom Typ Point besteht aus allen Verfahren mit Empfänger Typ Point deklariert (FakeScale).

Ein Methodenaufruf p.FakeScale ist gültig, da der Methodensatz von (der Typ von) p (Point) FakeScale enthält und die Argumentliste (10) der Parameterliste (int) von FakeScale.

Der Methodensatz vom Typ * Punkt besteht aus allen Methoden, die mit dem Empfängertyp * Punkt (RealScale) deklariert sind.

Da p adressierbar ist (p ist eine Variable) und der p & Verfahren Satz enthält RealScale, p.RealScale() ist eine Abkürzung für (& p) .RealScale().


Auch hierzu finden Sie meine Antwort auf Ihre frühere Frage: How to invoke a method with pointer receiver after type assertion?.