slices.MinFunc selects one element from a slice according to a caller-defined ordering. Unlike sorting, it does not rearrange the input, and unlike a field-specific loop, it makes the comparison rule an explicit part of the operation.

Its standard-library signature accepts any element type:

func MinFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E

The comparison function returns a negative value when a precedes b, a positive value when a follows b, and zero when the two values are equal under the chosen order.

Minimum can be defined over one struct field

Struct values have no general language-level ordering, but an application can define one over a field. A queue record, for example, can be ordered by its numeric priority:

package main

import (
    "cmp"
    "fmt"
    "slices"
)

type Job struct {
    ID       string
    Priority int
}

func main() {
    jobs := []Job{
        {ID: "render", Priority: 8},
        {ID: "index", Priority: 3},
        {ID: "backup", Priority: 5},
    }

    selected := slices.MinFunc(jobs, func(a, b Job) int {
        return cmp.Compare(a.Priority, b.Priority)
    })

    fmt.Println(selected.ID) // index
}

The slice remains in its original order. Only the selected value is returned.

That distinction matters when the minimum is needed once but the surrounding sequence has its own meaningful order. Sorting the entire slice would perform a broader mutation than the selection requires.

Equal minima resolve to the first element

A comparison function can consider distinct values equal. When several elements are minimal according to cmp, MinFunc returns the first such element in slice order.

jobs := []Job{
    {ID: "alpha", Priority: 2},
    {ID: "beta", Priority: 2},
    {ID: "gamma", Priority: 7},
}

selected := slices.MinFunc(jobs, func(a, b Job) int {
    return cmp.Compare(a.Priority, b.Priority)
})

fmt.Println(selected.ID) // alpha

This gives ties a deterministic result without adding another comparison key. The original slice order becomes the tie boundary.

If the domain requires a different tie policy, the comparator can encode it directly. Priority can be the primary key and an identifier can become the secondary key:

selected := slices.MinFunc(jobs, func(a, b Job) int {
    if n := cmp.Compare(a.Priority, b.Priority); n != 0 {
        return n
    }
    return cmp.Compare(a.ID, b.ID)
})

Under that comparator, two records with the same priority are no longer equal unless their identifiers also compare equally.

Comparator direction defines the selected extreme

MinFunc has no knowledge of fields such as priority, timestamp, size, or score. It only follows the ordering supplied by cmp.

Reversing the comparator reverses the meaning of the minimum:

selected := slices.MinFunc(jobs, func(a, b Job) int {
    return cmp.Compare(b.Priority, a.Priority)
})

With this order, larger numeric priorities precede smaller ones, so the function selects the numerically largest priority. The function name describes the minimum under the comparator, not necessarily the smallest raw field value.

Keeping comparator direction visible and consistent is especially useful when the same order is shared with slices.SortFunc, slices.IsSortedFunc, or other comparison-based operations.

Empty input is a contract boundary

MinFunc panics when the input slice is empty. It does not return a zero value or a second Boolean indicating absence.

Code that receives optional collections therefore needs to establish non-emptiness before selection:

if len(jobs) == 0 {
    // handle the absence of a candidate
} else {
    selected := slices.MinFunc(jobs, func(a, b Job) int {
        return cmp.Compare(a.Priority, b.Priority)
    })
    _ = selected
}

This keeps absence handling outside the comparator. The comparison function is called only for actual elements and can remain focused on ordering.

The returned struct is a value copy

For a slice of struct values, MinFunc returns an element value. Assigning to fields of that returned struct does not rewrite the corresponding struct stored in the slice.

selected := slices.MinFunc(jobs, func(a, b Job) int {
    return cmp.Compare(a.Priority, b.Priority)
})

selected.Priority = 100

The matching element inside jobs retains its prior Priority. This follows ordinary Go assignment semantics.

Reference-bearing fields are still copied shallowly. If a selected struct contains a map, slice, pointer, or another reference-like value, the returned struct and the stored element can still refer to the same underlying state through that field.

Selection avoids imposing sorted state

A minimum operation and a sort answer different structural needs. Sorting establishes an order across every element and mutates the slice. MinFunc identifies one extreme under the comparator while leaving the sequence untouched.

That narrower effect is useful when order must remain stable for another purpose, when only one candidate is needed, or when the comparison rule belongs to the selection itself rather than to the persistent representation of the collection.

The central constraint remains the comparator: it defines both which element counts as minimal and which distinct values count as ties. Once that ordering is explicit, slices.MinFunc provides a compact selection operation without turning the slice into a sorted data structure.