Well, is fmt.Stringer supported? The result might surprise you:
req := expvar.NewInt("requests")
req.Add(1)
attr := slog.Any("requests", req)
slog.New(slog.NewTextHandler(os.Stderr, nil)).Info("text", attr)
slog.New(slog.NewJSONHandler(os.Stderr, nil)).Info("json", attr)
This code produces
time=2025-09-12T13:15:42.125+02:00 level=INFO msg=text requests=1
{"time":"2025-09-12T13:15:42.125555+02:00","level":"INFO","msg":"json","requests":{}}
So the code that uses slog but does not know what handler will be used can't rely on it lazily calling the `String() string` method: half of the standard handlers do that, half don't.