Поведінка надзвичайно схожа на Array.Resize
метод у .NET. Щоб зрозуміти, що відбувається, може бути корисно поглянути на історію .
лексеми на мовах C, C ++, Java, C # та Swift.
У C структура - це не що інше, як сукупність змінних. Застосування .
змінної до змінної типу структури матиме доступ до змінної, що зберігається в структурі. Покажчики на об'єкти не містять агрегатів змінних, а ідентифікують їх. Якщо є покажчик, який ідентифікує структуру, файл->
оператор може бути використаний для доступу до змінної, що зберігається в структурі, ідентифікованій вказівником.
У C ++ структури та класи не тільки агрегують змінні, але й можуть до них додавати код. Використання .
для виклику методу буде вимагати від змінної, щоб цей метод діяв на вміст самої змінної ; використання ->
змінної, яка ідентифікує об'єкт, попросить цей метод діяти на ідентифікований об'єкт змінною.
У Java всі користувацькі типи змінних просто ідентифікують об'єкти, і виклик методу на змінну покаже методу, який об'єкт ідентифікується змінною. Змінні не можуть утримувати будь-який складний тип даних безпосередньо, а також не існує засобів, за допомогою яких метод може отримати доступ до змінної, на основі якої він викликається. Ці обмеження, хоча і семантично обмежують, значно спрощують час виконання та полегшують перевірку байт-коду; такі спрощення зменшили накладні витрати ресурсів на Java у той час, коли ринок був чутливим до таких проблем, і тим самим допомогли йому набути популярності на ринку. Вони також означали, що немає необхідності в маркері, еквівалентному .
використаному в C або C ++. Хоча Java могла використовувати ->
так само, як C і C ++, творці вирішили використовувати односимвольні.
оскільки це не було потрібно для будь-яких інших цілей.
У C # та інших мовах .NET змінні можуть або ідентифікувати об'єкти, або безпосередньо утримувати складені типи даних. При використанні для змінної складеного типу даних .
впливає на вміст змінної; при використанні на змінну контрольного типу .
діє на об'єкт ідентифікованийним. Для деяких видів операцій семантичне розрізнення не є особливо важливим, але для інших воно є важливим. Найбільш проблемними ситуаціями є ситуації, коли метод складеного типу даних, який змінює змінну, на основі якої вона викликається, викликається змінною лише для читання. Якщо робиться спроба викликати метод для значення або змінної, доступної лише для читання, компілятори, як правило, копіюють змінну, дозволяють методу діяти на неї та відхиляють змінну. Як правило, це безпечно для методів, які читають лише змінну, але не безпечно для методів, які в неї записують. На жаль, .does ще не має жодних засобів, які б вказували, які методи можна безпечно використовувати з такою заміною, а які ні.
У Swift методи на агрегатах можуть чітко вказати, чи будуть вони змінювати змінну, на основі якої вони викликаються, і компілятор заборонить використання мутуючих методів для змінних, доступних лише для читання (замість того, щоб вони мутували тимчасові копії змінної, яка потім викинути). Через це розрізнення використання .
маркера для виклику методів, що модифікують змінні, на основі яких вони викликаються, набагато безпечніше в Swift, ніж у .NET. На жаль, той факт, що .
для цієї мети використовується той самий маркер, що діє на зовнішній об’єкт, ідентифікований змінною, означає можливість плутанини.
Якби машина часу і повернулася до створення C # та / або Swift, можна було б ретроактивно уникнути великої плутанини, пов’язаної з такими проблемами, завдяки використанню мов .
і ->
жетонів набагато ближче до використання C ++. Методи як агрегатів, так і посилальних типів можуть використовуватись як .
для дії на змінну, на яку вони були викликані, так і ->
для дії на значення (для композитів) або на ідентифіковану цим річ (для еталонних типів). Проте жодна мова не розроблена таким чином.
У C # звичайною практикою методу модифікації змінної, на основі якої він викликається, є передача змінної як ref
параметра методу. Таким чином, виклик Array.Resize(ref someArray, 23);
при someArray
ідентифікації масиву з 20 елементів призведе someArray
до ідентифікації нового масиву з 23 елементів, не впливаючи на вихідний масив. Використання ref
ясного пояснює, що від методу слід очікувати модифікації змінної, на основі якої він викликається. У багатьох випадках вигідно мати можливість змінювати змінні без використання статичних методів; Швидкі адреси, що означає використання .
синтаксису. Недоліком є те, що він втрачає уточнення щодо того, які методи діють на змінні, а які - на значення.