Przejdź do głównej zawartości

Strategie edycji inline: Wskazówki 46-60

Edycja inline (Ctrl+K) to miejsce, gdzie język naturalny spotyka się z precyzyjną transformacją kodu. Te 15 wskazówek nauczą cię władać tą potężną funkcją od szybkich poprawek po wyrafinowane operacje refaktoryzacji.

Twoje zaznaczenie określa zakres transformacji:

// Zaznacz tylko instrukcję return:
return data;
// Ctrl+K: "Dodaj sprawdzenie null"
// Wynik wpływa tylko na return:
return data || [];

Przekształć niejasne żądania w precyzyjne instrukcje:

❌ Niejasne

“Ulepsz to” “Napraw to” “Optymalizuj”

✅ Konkretne

“Dodaj walidację wejścia dla null i pustych stringów” “Przekonwertuj callbacki na async/await” “Wyodrębnij magiczne liczby jako nazwane stałe”

Przykładowe transformacje:

// Oryginał
function calc(x, y) {
return x * 0.1 + y * 0.15;
}
// Niejasne: "Zrób to jaśniejsze"
// Konkretne: "Wyodrębnij stawki podatkowe jako stałe i dodaj walidację parametrów"
// Wynik:
const TAX_RATE_BASE = 0.1;
const TAX_RATE_ADDITIONAL = 0.15;
function calc(x, y) {
if (typeof x !== 'number' || typeof y !== 'number') {
throw new TypeError('Oba parametry muszą być liczbami');
}
return x * TAX_RATE_BASE + y * TAX_RATE_ADDITIONAL;
}

Wskazówka 48: Używaj wskazówek kontekstowych w instrukcjach

Dział zatytułowany „Wskazówka 48: Używaj wskazówek kontekstowych w instrukcjach”

Odwołuj się do otaczającego kodu w swoich instrukcjach:

// Zaznacz funkcję
async function createUser(data) {
return db.users.insert(data);
}
// Ctrl+K: "Dodaj taką samą walidację jak funkcja updateUser powyżej"
// Cursor spogląda na updateUser i stosuje podobną walidację
// Lub bądź jawny odnośnie wzorców:
// "Dodaj walidację pasującą do naszego standardowego wzorca API z Joi"

Buduj złożone transformacje stopniowo:

  1. Pierwsza edycja: “Przekonwertuj na TypeScript z właściwymi typami”
  2. Druga edycja: “Dodaj obsługę błędów”
  3. Trzecia edycja: “Dodaj dokumentację JSDoc”
  4. Czwarta edycja: “Wyodrębnij magiczne liczby do stałych”

Każda edycja buduje na poprzedniej, utrzymując kontekst:

// Oryginał
function process(items) {
return items.filter(i => i.price > 100).map(i => i.price * 1.2);
}
// Po połączonych edycjach:
/**
* Przetwarza elementy przez filtrowanie i stosowanie narzutu
* @param items - Tablica elementów z właściwością price
* @returns Tablica dostosowanych cen dla elementów premium
*/
const PREMIUM_THRESHOLD = 100;
const MARKUP_RATE = 1.2;
function process(items: Array<{price: number}>): number[] {
try {
if (!Array.isArray(items)) {
throw new TypeError('Items musi być tablicą');
}
return items
.filter(item => item.price > PREMIUM_THRESHOLD)
.map(item => item.price * MARKUP_RATE);
} catch (error) {
console.error('Błąd przetwarzania elementów:', error);
return [];
}
}

Edycja inline rozpoznaje i stosuje wzorce:

// Zaznacz wiele podobnych funkcji
getUserById(id) { return db.users.find(id); }
getPostById(id) { return db.posts.find(id); }
getCommentById(id) { return db.comments.find(id); }
// Ctrl+K: "Przekonwertuj na generyczną funkcję factory"
// Wynik:
function createFindById(collection) {
return (id) => db[collection].find(id);
}
const getUserById = createFindById('users');
const getPostById = createFindById('posts');
const getCommentById = createFindById('comments');

Edycja inline doskonale radzi sobie z transformacjami strukturalnymi:

// Zaznacz:
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
];
// Ctrl+K: "Przekonwertuj na obiekt indeksowany przez id"
// Wynik:
const users = {
1: { id: 1, name: 'Alice' },
2: { id: 2, name: 'Bob' }
};

Używaj edycji inline do ulepszeń wydajności:

// Zaznacz nieefektywny kod:
function findDuplicates(arr) {
const duplicates = [];
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j] && !duplicates.includes(arr[i])) {
duplicates.push(arr[i]);
}
}
}
return duplicates;
}
// Ctrl+K: "Optymalizuj używając Set dla złożoności O(n)"
// Wynik:
function findDuplicates(arr) {
const seen = new Set();
const duplicates = new Set();
for (const item of arr) {
if (seen.has(item)) {
duplicates.add(item);
} else {
seen.add(item);
}
}
return Array.from(duplicates);
}

Przekształcaj kod aby implementować konkretne wzorce:

// Zaznacz klasę z bezpośrednimi zależnościami:
class OrderService {
constructor() {
this.database = new Database();
this.emailer = new EmailService();
this.logger = new Logger();
}
}
// Ctrl+K: "Zastosuj wzorzec dependency injection"
// Wynik:
class OrderService {
constructor(database, emailer, logger) {
this.database = database;
this.emailer = emailer;
this.logger = logger;
}
}
// Z definicjami interfejsów:
interface IDatabase { /* ... */ }
interface IEmailService { /* ... */ }
interface ILogger { /* ... */ }
class OrderService {
constructor(
private database: IDatabase,
private emailer: IEmailService,
private logger: ILogger
) {}
}

Dziel złożony kod na moduły:

// Zaznacz dużą funkcję
// Ctrl+K: "Wyodrębnij logikę walidacji do oddzielnych funkcji"
// Lub bardziej konkretnie:
// "Wyodrębnij każdy krok do nazwanej funkcji podążając za zasadą pojedynczej odpowiedzialności"

Przekształcaj funkcje w w pełni przetestowany kod:

// Zaznacz funkcję:
export function parsePrice(priceString: string): number {
const cleaned = priceString.replace(/[$,]/g, '');
return parseFloat(cleaned);
}
// Ctrl+K: "Dodaj kompleksowe przypadki testowe włączając przypadki brzegowe"
// Generuje (w pliku testowym):
describe('parsePrice', () => {
it('powinien parsować podstawowe stringi cen', () => {
expect(parsePrice('$10.99')).toBe(10.99);
expect(parsePrice('$1,234.56')).toBe(1234.56);
});
it('powinien obsługiwać przypadki brzegowe', () => {
expect(parsePrice('$0')).toBe(0);
expect(parsePrice('$0.01')).toBe(0.01);
expect(parsePrice('$.99')).toBe(0.99);
});
it('powinien obsługiwać nieprawidłowe wejścia', () => {
expect(parsePrice('')).toBe(NaN);
expect(parsePrice('abc')).toBe(NaN);
expect(parsePrice('$')).toBe(NaN);
});
it('powinien obsługiwać duże liczby', () => {
expect(parsePrice('$1,000,000.00')).toBe(1000000);
});
});

Generuj dokumentację świadomą kontekstu:

// Zaznacz złożoną funkcję
// Ctrl+K: "Dodaj JSDoc z przykładami opartymi na implementacji"
// Edycja inline analizuje kod i generuje:
/**
* Oblicza odsetki składane od inwestycji
* @param {number} principal - Początkowa kwota inwestycji
* @param {number} rate - Roczna stopa procentowa (jako dziesiętna, np. 0.05 dla 5%)
* @param {number} time - Okres inwestycji w latach
* @param {number} n - Liczba składań odsetek rocznie
* @returns {number} Końcowa kwota po odsetkach składanych
*
* @example
* // Oblicz miesięczne odsetki składane dla $1000 przy 5% przez 2 lata
* calculateCompoundInterest(1000, 0.05, 2, 12); // Zwraca 1104.94
*
* @example
* // Oblicz roczne odsetki składane
* calculateCompoundInterest(5000, 0.03, 10, 1); // Zwraca 6719.58
*/

Przekształcaj optymistyczny kod w kod gotowy na produkcję:

// Zaznacz:
async function fetchUserData(userId) {
const response = await fetch(`/api/users/${userId}`);
const data = await response.json();
return data;
}
// Ctrl+K: "Dodaj kompleksową obsługę błędów z logiką retry"
// Wynik:
async function fetchUserData(userId, maxRetries = 3) {
if (!userId) {
throw new Error('userId jest wymagane');
}
let lastError;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await fetch(`/api/users/${userId}`);
if (!response.ok) {
if (response.status === 404) {
throw new Error(`Użytkownik ${userId} nie został znaleziony`);
}
throw new Error(`Błąd HTTP! status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
lastError = error;
if (attempt < maxRetries &&
!error.message.includes('nie został znaleziony')) {
console.warn(`Próba ${attempt} nie powiodła się, ponawiam...`);
await new Promise(resolve =>
setTimeout(resolve, 1000 * attempt)
);
}
}
}
throw new Error(`Niepowodzenie po ${maxRetries} próbach: ${lastError.message}`);
}

Wskazówka 58: Inteligentnie obsługuj przypadki brzegowe

Dział zatytułowany „Wskazówka 58: Inteligentnie obsługuj przypadki brzegowe”

Edycja inline może zidentyfikować i obsłużyć przypadki brzegowe:

// Zaznacz funkcję, która potrzebuje obsługi przypadków brzegowych
// Ctrl+K: "Dodaj obsługę przypadków brzegowych dla null, undefined, pustych tablic i wartości granicznych"

Naciśnij Alt+Enter zamiast Enter dla szybkich pytań:

// Zaznacz kod
const result = data?.user?.profile?.email || 'default@example.com';
// Ctrl+K, następnie Alt+Enter: "Co robi ?."
// Cursor wyjaśnia optional chaining bez modyfikowania kodu

Porada pro Używaj szybkich pytań do zrozumienia kodu przed jego transformacją.

Twórz potężne przepływy pracy:

Inline Edit → Tab

Użyj edycji inline do rozpoczęcia refaktoryzacji, następnie Tab do ukończenia podobnych wzorców

Inline Edit → Agent

Użyj edycji inline do lokalnych zmian, następnie Agent do aktualizacji całego projektu

Wyszukiwanie → Inline Edit

Znajdź wszystkie wystąpienia, następnie grupowo przekształć z edycją inline

Przykładowy przepływ pracy:

Okno terminala
1. Wyszukaj wszystkie instrukcje "console.log"
2. Zaznacz każdą grupę wyników
3. Ctrl+K: "Zamień na odpowiednie wywołania logger.debug"
4. Przejrzyj i zastosuj zmiany

✅ Rób:

  • Bądź konkretny odnośnie pożądanych zmian
  • Zaznaczaj odpowiedni zakres
  • Łącz proste transformacje
  • Przeglądaj wygenerowany kod
  • Używaj do refaktoryzacji wzorców

❌ Nie rób:

  • Składania niejasnych żądań
  • Transformowania zbyt dużo na raz
  • Pomijania przeglądu kodu
  • Ignorowania przypadków brzegowych
  • Nadpisywania bez zrozumienia
  1. Wyzwanie refaktoryzacji: Weź 50-liniową funkcję i podziel ją na mniejsze funkcje używając tylko edycji inline.

  2. Wyzwanie bezpieczeństwa typów: Przekonwertuj plik JavaScript na TypeScript z właściwymi typami używając połączonych edycji inline.

  3. Zastosowanie wzorca: Zastosuj trzy różne wzorce projektowe do klasy używając edycji inline.

  4. Generowanie testów: Wygeneruj kompletne pokrycie testów dla modułu używając edycji inline.


Opanowałeś precyzyjną transformację kodu z edycją inline. Teraz eksploruj Optymalizacja agent i chat, aby obsługiwać złożone operacje na wielu plikach i wykorzystywać AI do podejmowania decyzji architektonicznych.