Repository: go
Issue: expvar: Func does not implement Var
Labels: NeedsInvestigation

### What version of Go are you using (`go version`)?

Go playground, at version go1.15.5.

### Does this issue reproduce with the latest release?

Yes, this is present in go1.15.3, and in the playground at go1.15.5.

### What operating system and processor architecture are you using (`go env`)?

Go playground, but first seen on linux/amd64.

### What did you do?

Used expvar.Publish with expvar.Func, with a function that returns a struct which encoding/json cannot serialize.

https://play.golang.org/p/9wpvZMJtDmw

```
package main

import (
	"bytes"
	"encoding/json"
	"expvar"
	"log"
	"net/http"
	"net/http/httptest"
)

func main() {
	try := func() {
		r, err := http.NewRequest("GET", "/debug/vars", nil)
		if err != nil {
			log.Fatal(err)
		}
		w := &httptest.ResponseRecorder{Body: new(bytes.Buffer)}
		expvar.Handler().ServeHTTP(w, r)

		err = json.Unmarshal(w.Body.Bytes(), new(interface{}))
		if err != nil {
			log.Fatalf("Invalid JSON: %v\n%s\n", err, w.Body)
		}
		log.Printf("Valid JSON")
	}

	try()

	log.Printf("Publishing new value")
	expvar.Publish("config", expvar.Func(func() interface{} {
		return struct {
			Fn func()
		}{}
	}))

	try()
}
```

### What did you expect to see?

I expected expvar.Func to implement expvar.Var, meaning it would always return valid JSON. I expected that an HTTP request to /debug/vars would return a valid JSON object. I expected that expvar.Func would recover from an error by returning a boring but valid value, such as `null`.

### What did you see instead?

The String method of expvar.Func ignores the error return value from encoding/json.Marshal, so will return an empty string when the func returns a value that cannot be serialized to JSON.

https://github.com/golang/go/blob/go1.15.5/src/expvar/expvar.go#L261-L264

```
2009/11/10 23:00:00 Valid JSON
2009/11/10 23:00:00 Publishing new value
2009/11/10 23:00:00 Invalid JSON: invalid character ',' looking for beginning of value
{
"cmdline": ["/tmpfs/play"],
"config": ,
"memstats": {"Alloc":296512,"TotalAlloc":296512,"Sys":71650312,"Lookups":0,"Mallocs":1604,"Frees":320,"HeapAlloc":296512,"HeapSys":66781184,"HeapIdle":66035712,"HeapInuse":745472,"HeapReleased":66002944,"HeapObjects":1284,"StackInuse":327680,"StackSys":327680,"MSpanInuse":19040,"MSpanSys":32768,"MCacheInuse":13888,"MCacheSys":16384,"BuckHashSys":3806,"GCSys":3826440,"OtherSys":662050,"NextGC":4473924,"LastGC":0,"PauseTotalNs":0,"PauseNs":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"PauseEnd":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"NumGC":0,"NumForcedGC":0,"GCCPUFraction":0,"EnableGC":true,"DebugGC":false,"BySize":[{"Size":0,"Mallocs":0,"Frees":0},{"Size":8,"Mallocs":46,"Frees":0},{"Size":16,"Mallocs":676,"Frees":0},{"Size":32,"Mallocs":70,"Frees":0},{"Size":48,"Mallocs":161,"Frees":0},{"Size":64,"Mallocs":34,"Frees":0},{"Size":80,"Mallocs":6,"Frees":0},{"Size":96,"Mallocs":10,"Frees":0},{"Size":112,"Mallocs":4,"Frees":0},{"Size":128,"Mallocs":8,"Frees":0},{"Size":144,"Mallocs":8,"Frees":0},{"Size":160,"Mallocs":16,"Frees":0},{"Size":176,"Mallocs":5,"Frees":0},{"Size":192,"Mallocs":0,"Frees":0},{"Size":208,"Mallocs":35,"Frees":0},{"Size":224,"Mallocs":1,"Frees":0},{"Size":240,"Mallocs":0,"Frees":0},{"Size":256,"Mallocs":13,"Frees":0},{"Size":288,"Mallocs":73,"Frees":0},{"Size":320,"Mallocs":2,"Frees":0},{"Size":352,"Mallocs":10,"Frees":0},{"Size":384,"Mallocs":19,"Frees":0},{"Size":416,"Mallocs":8,"Frees":0},{"Size":448,"Mallocs":0,"Frees":0},{"Size":480,"Mallocs":1,"Frees":0},{"Size":512,"Mallocs":3,"Frees":0},{"Size":576,"Mallocs":5,"Frees":0},{"Size":640,"Mallocs":4,"Frees":0},{"Size":704,"Mallocs":2,"Frees":0},{"Size":768,"Mallocs":0,"Frees":0},{"Size":896,"Mallocs":7,"Frees":0},{"Size":1024,"Mallocs":12,"Frees":0},{"Size":1152,"Mallocs":5,"Frees":0},{"Size":1280,"Mallocs":3,"Frees":0},{"Size":1408,"Mallocs":1,"Frees":0},{"Size":1536,"Mallocs":0,"Frees":0},{"Size":1792,"Mallocs":5,"Frees":0},{"Size":2048,"Mallocs":2,"Frees":0},{"Size":2304,"Mallocs":4,"Frees":0},{"Size":2688,"Mallocs":3,"Frees":0},{"Size":3072,"Mallocs":0,"Frees":0},{"Size":3200,"Mallocs":0,"Frees":0},{"Size":3456,"Mallocs":0,"Frees":0},{"Size":4096,"Mallocs":8,"Frees":0},{"Size":4864,"Mallocs":2,"Frees":0},{"Size":5376,"Mallocs":1,"Frees":0},{"Size":6144,"Mallocs":2,"Frees":0},{"Size":6528,"Mallocs":0,"Frees":0},{"Size":6784,"Mallocs":0,"Frees":0},{"Size":6912,"Mallocs":0,"Frees":0},{"Size":8192,"Mallocs":1,"Frees":0},{"Size":9472,"Mallocs":0,"Frees":0},{"Size":9728,"Mallocs":0,"Frees":0},{"Size":10240,"Mallocs":8,"Frees":0},{"Size":10880,"Mallocs":0,"Frees":0},{"Size":12288,"Mallocs":0,"Frees":0},{"Size":13568,"Mallocs":0,"Frees":0},{"Size":14336,"Mallocs":0,"Frees":0},{"Size":16384,"Mallocs":0,"Frees":0},{"Size":18432,"Mallocs":0,"Frees":0},{"Size":19072,"Mallocs":0,"Frees":0}]}
}
```