func (rs *Rows) nextLocked() (doClose, ok bool) { if rs.closed { return false, false } // Lock the driver connection before calling the driver interface // rowsi to prevent a Tx from rolling back the connection at the same time. rs.dc.Lock() defer rs.dc.Unlock() if rs.lastcols == nil { rs.lastcols = make([]driver.Value, len(rs.rowsi.Columns())) } rs.lasterr = rs.rowsi.Next(rs.lastcols) ------- func (rs *Rows) Next() bool { // If the user's calling Next, they're done with their previous row's Scan // results (any RawBytes memory), so we can release the read lock that would // be preventing awaitDone from calling close. rs.closemuRUnlockIfHeldByScan() if rs.contextDone.Load() != nil { return false } var doClose, ok bool withLock(rs.closemu.RLocker(), func() { doClose, ok = rs.nextLocked() }) ---------- func (rs *Rows) Scan(dest ...any) error { fmt.Printf("驱动内部的 sCan %#v \n", dest) if rs.closemuScanHold { // This should only be possible if the user calls Scan twice in a row // without calling Next. return fmt.Errorf("sql: Scan called without calling Next (closemuScanHold)") } rs.closemu.RLock() if rs.lasterr != nil && rs.lasterr != io.EOF { rs.closemu.RUnlock() return rs.lasterr } if rs.closed { err := rs.lasterrOrErrLocked(errRowsClosed) rs.closemu.RUnlock() return err } if scanArgsContainRawBytes(dest) { rs.closemuScanHold = true } else { rs.closemu.RUnlock() } if rs.lastcols == nil { rs.closemuRUnlockIfHeldByScan() return errors.New("sql: Scan called without calling Next") } if len(dest) != len(rs.lastcols) { fmt.Println(" len(rs.lastcols)", len(rs.lastcols)) fmt.Println(" len(dest) ", len(dest), dest) fmt.Println("列数据不匹配") rs.closemuRUnlockIfHeldByScan() return fmt.Errorf("sql: expected %d destination arguments in Scan, not %d", len(rs.lastcols), len(dest)) } fmt.Println("列数据匹配") for i, sv := range rs.lastcols { err := convertAssignRows(dest[i], sv, rs) if err != nil { rs.closemuRUnlockIfHeldByScan() return fmt.Errorf(`sql: Scan error on column index %d, name %q: %w`, i, rs.rowsi.Columns()[i], err) } } return nil }