2016-11-12 5 views
5

я чувствую себя немного потеряли, используя быстрый параметр Inout в следующем коде:Является ли swift inout параметром переменная или указатель?

var shouldContinue: Bool = true 

func doSomeWork1(shouldContinue: inout Bool) 
{ 
    while shouldContinue 
    { 
     // ERROR: the compiler wants: doSomeWork2(shouldContinue: &shouldContinue) 
     doSomeWork2(shouldContinue: shouldContinue) 
    } 
} 

func doSomeWork2(shouldContinue: inout Bool) 
{ 
    while shouldContinue 
    { 

    } 
} 

Почему компилятор хочет doSomeWork2(shouldContinue: &shouldContinue) вместо the compiler wants: doSomeWork2(shouldContinue: shouldContinue)? is not shouldContinue уже указатель в области doSomeWork1() ???

ответ

7

Быть указателем является лишь побочным эффектом процесса оптимизации для неточных параметров. Они фактически работают по-разному, используя copy-in copy-out. Таким образом, внутри функции этот параметр обрабатывается как обычная переменная, а не указатель. Если вы передадите его другой функции, которая принимает параметр inout, вы должны пометить его как таковой.

In-Out передаются параметры следующим образом:

Когда функция вызывается, значение аргумента копируется.

В теле функции копия изменяется.

Когда функция возвращается, значение копии присваивается исходному аргументу.

Это поведение известно как копирование или копирование по результату. Например, для , когда вычисленное свойство или свойство с наблюдателями имеет значение , переданное как входной параметр, его получатель вызывается как часть вызова функции , и его сеттер вызывается как часть возврата функции.

В качестве оптимизации, когда аргумент представляет собой значение, сохраненное на физическом адресе в памяти, такое же место в памяти используется как внутри, так и вне тела функции. Оптимизированное поведение известно как вызов по ссылке ; он удовлетворяет всем требованиям копии модели при удалении накладных расходов на копирование. Напишите свой код , используя модель, полученную путем копирования в копии, не зависящую от оптимизации по запросу , так что она ведет себя правильно или без оптимизации.

In-Out Parameters

+0

Спасибо за Ваш ответ. Если я правильно вас понимаю, поведение с копированием в копии означает, что я не могу использовать свою переменную bool, чтобы отменить работу, выполненную в другом потоке? Иль означает, что если я изменил значение исходного 'shouldContinue', он не изменится внутри функций, но старое значение будет восстановлено при возврате из функций? – Adeline

+0

Да, вы не можете использовать его между потоками. Вы можете создать класс с булевым полем, а затем использовать экземпляр этого класса в нескольких потоках. И в этом случае вам не нужен параметр inout. Экземпляр класса - это ссылка (указатель), которая будет передана, и вы будете читать и записывать одно и то же логическое значение из нескольких потоков. –

+0

есть ли «более простой способ»? Создание класса, содержащего логическое значение, кажется немного перегруженным/беспорядочным. – Adeline

 Смежные вопросы

  • Нет связанных вопросов^_^