使用govmomi库在golang中设置零点

I'm trying to use the govmomi library (https://github.com/vmware/govmomi) to make some automated changes to a VM but I can't seem to get around the nil pointer exceptions on line 134 and 136 for the last few hours. I got it to work at one point but then I'm not sure what I'm doing wrong now as I've tried so many combos but nothing seems to work now...

package main

import (
    "context"
    "flag"
    "github.com/vmware/govmomi"
    "github.com/vmware/govmomi/vim25"
    "github.com/vmware/govmomi/vim25/soap"
    "net/url"
    "os"
    "strings"

    "fmt"

    "github.com/vmware/govmomi/govc/flags"

    "github.com/vmware/govmomi/vim25/types"
    "log"
)


type change struct {
    *flags.VirtualMachineFlag
}

const (
    envURL      = "GOVC_URL"
    envUserName = "GOVC_USERNAME"
    envPassword = "GOVC_PASSWORD"
    envInsecure = "GOVC_INSECURE"
)

// getEnvString returns string from environment variable.
func getEnvString(v string, def string) string {
    r := os.Getenv(v)
    if r == "" {
        return def
    }

    return r
}

// getEnvBool returns boolean from environment variable.
func getEnvBool(v string, def bool) bool {
    r := os.Getenv(v)
    if r == "" {
        return def
    }

    switch strings.ToLower(r[0:1]) {
    case "t", "y", "1":
        return true
    }

    return false
}

var urlDescription = fmt.Sprintf("ESX or vCenter URL [%s]", envURL)
var urlFlag = flag.String("url", getEnvString(envURL, "https://username:password@host"+vim25.Path), urlDescription)

var insecureDescription = fmt.Sprintf("Don't verify the server's certificate chain [%s]", envInsecure)
var insecureFlag = flag.Bool("insecure", getEnvBool(envInsecure, false), insecureDescription)

func processOverride(u *url.URL) {
    envUsername := os.Getenv(envUserName)
    envPassword := os.Getenv(envPassword)

    // Override username if provided
    if envUsername != "" {
        var password string
        var ok bool

        if u.User != nil {
            password, ok = u.User.Password()
        }

        if ok {
            u.User = url.UserPassword(envUsername, password)
        } else {
            u.User = url.User(envUsername)
        }
    }

    // Override password if provided
    if envPassword != "" {
        var username string

        if u.User != nil {
            username = u.User.Username()
        }

        u.User = url.UserPassword(username, envPassword)
    }
}

func NewClient(ctx context.Context) (*govmomi.Client, error) {
    flag.Parse()

    // Parse URL from string
    u, err := soap.ParseURL(*urlFlag)
    if err != nil {
        return nil, err
    }

    // Override username and/or password as required
    processOverride(u)

    // Connect and log in to ESX or vCenter
    return govmomi.NewClient(ctx, u, *insecureFlag)
}

func main() {

    ctx := context.Background()

    // Connect and login to ESX or vCenter
    c, err := NewClient(ctx)
    if err != nil {
        log.Fatal(err)
    }

    defer c.Logout(ctx)

    var spec *types.VirtualMachineConfigSpec

    var cmd *change

    var flip bool

    flip = false

    spec.VPMCEnabled = &flip

    vm, err := cmd.VirtualMachine()

    task, err := vm.Reconfigure(ctx, *spec)
    if err != nil {
        println(err)
    }

    fmt.Println(task.Wait(ctx))
}

the 2 lines that are throwing errors are:

spec.VPMCEnabled = &flip

and

vm, err := cmd.VirtualMachine()

both seem to throw the same panic: runtime error: invalid memory address or nil pointer dereference. If I comment out the first one throwing the error, the second one throws it then.

I think both are unrelated but I can't quite figure how how to do the dereferencing correctly.

----UPDATE EDIT 1--------------

I made some changes to this with the below response but still can't get around the error on at task, err := vm.Reconfigure(ctx, *spec)...

package main

import (
    "context"
    "flag"
    "github.com/vmware/govmomi"
    "github.com/vmware/govmomi/object"
    "github.com/vmware/govmomi/vim25"
    "github.com/vmware/govmomi/vim25/soap"
    "net/url"
    "os"
    "strings"

    "fmt"

    "github.com/vmware/govmomi/vim25/types"
    "log"
)


const (
    envURL      = "GOVC_URL"
    envUserName = "GOVC_USERNAME"
    envPassword = "GOVC_PASSWORD"
    envInsecure = "GOVC_INSECURE"
)

// getEnvString returns string from environment variable.
func getEnvString(v string, def string) string {
    r := os.Getenv(v)
    if r == "" {
        return def
    }

    return r
}

// getEnvBool returns boolean from environment variable.
func getEnvBool(v string, def bool) bool {
    r := os.Getenv(v)
    if r == "" {
        return def
    }

    switch strings.ToLower(r[0:1]) {
    case "t", "y", "1":
        return true
    }

    return false
}

var urlDescription = fmt.Sprintf("ESX or vCenter URL [%s]", envURL)
var urlFlag = flag.String("url", getEnvString(envURL, "https://username:password@host"+vim25.Path), urlDescription)

var insecureDescription = fmt.Sprintf("Don't verify the server's certificate chain [%s]", envInsecure)
var insecureFlag = flag.Bool("insecure", getEnvBool(envInsecure, false), insecureDescription)

func processOverride(u *url.URL) {
    envUsername := os.Getenv(envUserName)
    envPassword := os.Getenv(envPassword)

    // Override username if provided
    if envUsername != "" {
        var password string
        var ok bool

        if u.User != nil {
            password, ok = u.User.Password()
        }

        if ok {
            u.User = url.UserPassword(envUsername, password)
        } else {
            u.User = url.User(envUsername)
        }
    }

    // Override password if provided
    if envPassword != "" {
        var username string

        if u.User != nil {
            username = u.User.Username()
        }

        u.User = url.UserPassword(username, envPassword)
    }
}

func NewClient(ctx context.Context) (*govmomi.Client, error) {
    flag.Parse()

    // Parse URL from string
    u, err := soap.ParseURL(*urlFlag)
    if err != nil {
        return nil, err
    }

    // Override username and/or password as required
    processOverride(u)

    // Connect and log in to ESX or vCenter
    return govmomi.NewClient(ctx, u, *insecureFlag)
}

func main() {

    ctx := context.Background()

    // Connect and login to ESX or vCenter
    c, err := NewClient(ctx)
    if err != nil {
        log.Fatal(err)
    }

    defer c.Logout(ctx)

    var spec *types.VirtualMachineConfigSpec
    spec = new(types.VirtualMachineConfigSpec)


    var flip bool

    flip = false

    spec.VPMCEnabled = &flip

    var vm *object.VirtualMachine
    vm = new(object.VirtualMachine)


    task, err := vm.Reconfigure(ctx, *spec)
    if err != nil {
        println(err)
    }

    fmt.Println(task.Wait(ctx))

}

the full error I'm getting is this:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x280 pc=0x14e18f6]

goroutine 1 [running]:
github.com/vmware/govmomi/vim25.(*Client).RoundTrip(0x0, 0x1886f00, 0xc000016088, 0x1884140, 0xc000298720, 0x1884140, 0xc000298740, 0x300, 0x16e8ac0)
        /Users/ronakpatel/go/src/github.com/vmware/govmomi/vim25/client.go:89 +0x26
github.com/vmware/govmomi/vim25/methods.ReconfigVM_Task(0x1886f00, 0xc000016088, 0x1884060, 0x0, 0xc0002d0000, 0xc000288000, 0xc000080400, 0x0)
        /Users/ronakpatel/go/src/github.com/vmware/govmomi/vim25/methods/methods.go:10879 +0xb8
github.com/vmware/govmomi/object.VirtualMachine.Reconfigure(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1886f00, 0xc000016088, 0x0, ...)
        /Users/ronakpatel/go/src/github.com/vmware/govmomi/object/virtual_machine.go:207 +0x19b
main.main()
        /Users/ronakpatel/go/src/awesomeProject1/main.go:143 +0x1ec
exit status 2

----UPDATE EDIT 2----------

I changed somethings around and used the answer provided below but now I'm getting the error again but at this part: task, err := vm.Reconfigure(ctx, spec1)

Error:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x153d05a]

goroutine 1 [running]:
main.main()
        /Users/ronakpatel/go/src/awesomeProject1/main.go:134 +0x19a
exit status 2

Code:

spec1 := types.VirtualMachineConfigSpec{
    VPMCEnabled: &[]bool{false}[0],
}

var vm *object.VirtualMachine

var vmf *flags.VirtualMachineFlag

vmf, ctx = flags.NewVirtualMachineFlag(ctx)

vm, _ = vmf.VirtualMachine()

task, err := vm.Reconfigure(ctx, spec1)
if err != nil {
    println(err)
}

fmt.Println(task.Wait(ctx))
    var spec *types.VirtualMachineConfigSpec // error: spec is nil pointer
    spec = new(types.VirtualMachineConfigSpec) // fix: spec is not nil

    var cmd *change

    var flip bool

    flip = false

    // used here
    spec.VPMCEnabled = &flip

    vm, err := cmd.VirtualMachine()