GO - Come definire i metodi di tipo denominato?

0

In GO, rule is, i metodi possono essere definiti solo su named type e puntatore a named type .

In C, sotto codice , le operazioni sono definite sul tipo (ad esempio List ) ,

typedef struct List List; //list.h
typedef struct {

         bool(*canHandle)(ImplType);
        List*(*createList)();
        ....  
        const void*(*listGetItem)(List*, const int);
         .....
         void(*swap)(List*, int, int);
}ListHandler;


typedef struct{

  ListHandler *handler;
}ListRtti;


typedef struct List{

  ListRtti rtti; // operation on type List
  const void **array;
  /* For housekeeping - Array enhancement/shrink */
  int lastItemPosition;
  int size;
}List;

In Java, le operazioni sono definite sul tipo (ad esempio DList ),

public class DList {
  private DListNode sentinel;
  private int size;
  public void addItem(Object item){
    ...
  }
  ....
}

Ma in GO, codice di seguito, le operazioni sono consentite su named type e puntatore al tipo di nome .

package main

type Cat struct {
}

func (c Cat) foo() {
   // do stuff_
}

func (c *Cat) foo() {
  // do stuff_
}

func main() {

}

Domanda:

1)

Qual è l'idea di definire un metodo su un puntatore al tipo con nome?

2)

Come può sapere un programmatore in anticipo, se foo() deve funzionare come valore per valore / riferimento? Perché GO compiler limita il metodo di definizione su entrambi i puntatori named typed e al tipo named ?

    
posta overexchange 30.01.2017 - 17:31
fonte

1 risposta

2

La maggior parte delle lingue OOP passa l'oggetto corrente ("invocante") come puntatore o tipo di riferimento equivalente. In Java e C ++ l'invocante è chiamato this , in Python è un argomento esplicito chiamato self . In Java e Python questo è a costo zero perché i loro oggetti sono già tipi di riferimento. In C ++, usare un puntatore (o riferimento) è necessario perché quel linguaggio ha semantica del valore. Se this era un valore anziché un riferimento, la classe che definisce il metodo non può essere sottoclasse.

Come C ++, Go ha dei tipi di valore, ma in realtà non ha ereditarietà e non può sovrascrivere i metodi, quindi l'uso di un puntatore non è necessario .

Tuttavia, l'uso di un puntatore è utile quando:

  • si desidera modificare il richiamo, ad es. assegna a un campo di una struct.

  • il tipo è grande, quindi una copia sarebbe più costosa dell'utilizzo di un puntatore.

Al contrario, l'uso di un tipo non puntatore per il richiamo è utile se quel tipo è molto piccolo e se non si desidera modificare quell'oggetto. In generale, si usa un invocante senza puntatore per i tipi "primitivi" poiché sono piuttosto piccoli. Questo dovrebbe essere trattato come una micro-ottimizzazione; nella maggior parte dei casi si desidera un puntatore per i tipi definiti dall'utente.

    
risposta data 30.01.2017 - 18:05
fonte

Leggi altre domande sui tag