func (p Point) ReadValue(vv ValueVisitor) {
	switch v := p.Value.(type) {
	case int64:
		vv.VisitInt64Value(v)
	case float64:
		vv.VisitFloat64Value(v)
	case *Distribution:
		vv.VisitDistributionValue(v)
	case *Summary:
		vv.VisitSummaryValue(v)
	default:
		panic("unexpected value type")
	}
}
ReadValue accepts a ValueVisitor and calls the appropriate method with the
value of this point.
Consumers of Point should use this in preference to switching on the type
of the value directly, since new value types may be added.
package metricdata
import (
	"time"
)
type Point struct {
	Time time.Time
	Value interface{}
}
func NewFloat64Point(t time.Time, val float64) Point {
	return Point{
		Value: val,
		Time:  t,
	}
}
func NewInt64Point(t time.Time, val int64) Point {
	return Point{
		Value: val,
		Time:  t,
	}
}
func NewDistributionPoint(t time.Time, val *Distribution) Point {
	return Point{
		Value: val,
		Time:  t,
	}
}
func NewSummaryPoint(t time.Time, val *Summary) Point {
	return Point{
		Value: val,
		Time:  t,
	}
}
type ValueVisitor interface {
	VisitFloat64Value(float64)
	VisitInt64Value(int64)
	VisitDistributionValue(*Distribution)
	VisitSummaryValue(*Summary)
}