此功能的“惯用”版本是什么?

Trying to understand the mentality of Go. I wrote the following function which looks for *.txt files of a folder that have a date in the filename, get the latest date and return that date.

func getLatestDate(path string) (time.Time, error) {
    if fns, e := filepath.Glob(filepath.Join(path, "*.txt")); e == nil {
        re, _ := regexp.Compile(`_([0-9]{8}).txt$`)
        max := ""
        for _, fn := range fns {
            if ms := re.FindStringSubmatch(fn); ms != nil {
                if ms[1] > max {
                    max = ms[1]
                }
            }
        }
        date, _ := time.Parse("20060102", max)
        return date, nil
    } else {
        return time.Time{}, e
    }
}

What would be the more idiomatic version of this function, if there is one?

Here is my take

  1. Use MustCompile to compile a static regexp. This will panic if it doesn't compile and saves an error check
  2. Hoist compiling the regexp out of the function - you only need it compiled once. Note that I've called it with a lowercase initial letter so it won't be visible outside the package.
  3. Use an early return when checking errors - this saves indentation and is idiomatic go
  4. Use named return parameters for those early returns - saves defining nil values for types and typing in general (not to everyone's taste though)
  5. return time.Parse directly which checks the errors (you weren't before)

The code

var dateRe = regexp.MustCompile(`_([0-9]{8}).txt$`)

func getLatestDate(path string) (date time.Time, err error) {
    fns, err := filepath.Glob(filepath.Join(path, "*.txt"))
    if err != nil {
        return
    }
    max := ""
    for _, fn := range fns {
        if ms := dateRe.FindStringSubmatch(fn); ms != nil {
            if ms[1] > max {
                max = ms[1]
            }
        }
    }
    return time.Parse("20060102", max)
}

Here's how I would have written it. Don't ignore errors, use guard clauses for error handling, and don't recompile regexps inside a loop.

var datePat = regexp.MustCompile(`_([0-9]{8}).txt$`)

func getLatestDate(path string) (time.Time, error) {
    fns, err := filepath.Glob(filepath.Join(path, "*.txt"))
    if err != nil {
        return time.Time{}, err
    }
    max := time.Time{}
    for _, fn := range fns {
        if ms := re.FindStringSubmatch(fn); ms != nil {
            if t, err := time.Parse("20060102", ms[1]); err == nil && t.After(max) {
                max = t
            }
        }
    }
    return max, nil
}