2015-07-08 18 views
6

dire per alcuni molto semplice codice Golang:Golan funziona su una macchina virtuale?

package main 
import "fmt" 

func plus(a int, b int) int { 

    return a+b 
} 

func plusPlus(a,b,c int) int { 
    return a +b + c 
} 

func main() { 

    ptr := plus 
    ptr2 := plusPlus 

    fmt.Println(ptr) 
    fmt.Println(ptr2) 
} 

Questo ha il seguente output:

0x2000 
0x2020 

Cosa sta succedendo qui? Questo non sembra un puntatore a funzione, o qualsiasi tipo di puntatore per quella materia, che si troverà nello stack. Capisco anche che Go, pur offrendo alcune funzionalità di basso livello nel reparto threading, richiede anche un sistema operativo per il suo funzionamento; C è funzionale su tutte le piattaforme di computer e sistemi operativi possono essere scritti in esso mentre Go ha bisogno di un sistema operativo per funzionare e in effetti funziona solo su alcuni sistemi operativi al momento. I puntatori di funzione molto regolari indicano che questo funziona su una VM? O il compilatore è semplicemente collegato a funzioni di basso livello C?

+1

Dopo la registrazione del codice della libreria per vedere se 'fmt' o 'reflect' stava modificando i valori dei puntatori delle funzioni quando li stampavo, sono giunto alla conclusione che non lo fanno. Vai davvero solo mappe il tuo codice vicino al fondo dello spazio VM. :) – hobbs

+1

non lo sa e lo chiedi, perché votarlo? – vuhung3990

risposta

2

Sono valori della funzione:

package main 

import "fmt" 

func plus(a int, b int) int { 
    return a + b 
} 

func plusPlus(a, b, c int) int { 
    return a + b + c 
} 

func main() { 
    funcp := plus 
    funcpp := plusPlus 
    fmt.Println(funcp) 
    fmt.Println(funcpp) 
    fmt.Println(funcp(1, 2)) 
    fmt.Println(funcpp(1, 2, 3)) 
} 

uscita:

0x20000 
0x20020 
3 
6 
7

Go non viene eseguito su una macchina virtuale.

Dalla visualizzazione delle specifiche della lingua, ptr e ptr2 sono function values. Possono essere chiamati come ptr(1, 2) e ptr2(1, 2, 3).

Immergersi nell'implementazione, le variabili ptr e ptr2 sono puntatori ai valori di funzione. Vedere il documento di progettazione Function Call per informazioni sui valori funzionali. Notare la distinzione tra il valore della "funzione" della lingua e il valore "func" dell'implementazione.

perché l'API relflection utilizzato dal pacchetto indirectsfmt attraverso i valori FUNC per ottenere il puntatore per la stampa, la chiamata alla stampa il fmt.Println(ptr) indirizzo effettivo della funzione plus.

6

Go non viene eseguito su una macchina virtuale. Questi sono gli indirizzi effettivi delle funzioni.

Sulla mia macchina (vai 1.4.1, Linux amd64) il programma stampa

0x400c00 
0x400c20 

che sono diversi dai valori nel tuo esempio, ma ancora piuttosto basso. Verifica del codice compilato:

$ nm test | grep 'T main.plus' 
0000000000400c00 T main.plus 
0000000000400c20 T main.plusPlus 

questi sono gli indirizzi effettivi delle funzioni. func plus compila a soli 19 byte di codice, quindi plusPlus appare solo 32 (0x20) byte in seguito per soddisfare i requisiti di allineamento ottimali.

Per motivi di curiosità, ecco lo smontaggio di func plus da objdump -d, che dovrebbe fugare i dubbi che Go viene compilato in tutt'altro codice nativo:

0000000000400c00 <main.plus>: 
    400c00:  48 8b 5c 24 08   mov 0x8(%rsp),%rbx 
    400c05:  48 8b 6c 24 10   mov 0x10(%rsp),%rbp 
    400c0a:  48 01 eb    add %rbp,%rbx 
    400c0d:  48 89 5c 24 18   mov %rbx,0x18(%rsp) 
    400c12:  c3      retq 
Problemi correlati