2016-01-26 4 views
0

Я читал, что глобальные переменные являются плохими. Но как насчет глобальных функций? Скажем, я добавляю к моему проекту приложения iPhone файл с именем Globals.swift, содержащий func foo() { print("foo") }. Разве это не так плохо, потому что это может противоречить другим глобальным функциям с тем же именем? & подпись? По тому же аргументу, не так ли плохо использовать расширения для добавления новых методов к существующим типам?Swift: Являются ли глобальные функции плохой практикой?

ответ

6

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

Но это не то же самое, что глобальная видимость, несколькими способами.

Если вы определяете верхний уровень (aka global) func foo() в модуле (приложении или фреймворке) с именем MyTarget, то полная подпись для этой функции равна MyTarget.foo(). Даже если бы стандартная библиотека Swift объявила глобальный func foo(), ваш не обязательно конфликтует. (Тем не менее, любые сайты вызовов станут двусмысленными, поэтому вам нужно будет использовать имя модуля, чтобы отличать MyTarget.foo() и Swift.foo().)

Если ваш код находится в модуле, который будет использоваться другим кодом (например, совместно используемый общий между приложением iOS и целями расширения), ваш func foo() декларация - internal. Таким образом, другой код, импортирующий ваш модуль, может объявить свой собственный func foo() и называть его только foo(), независимо от того, существует ли ваша функция. Это влияет только на модули, импортирующие ваши, если объявлено как public func foo(). (И даже тогда вызывающие абоненты могут disambiguate использовать имя модуля, как указано выше.) Кроме того, вы можете объявить свою функцию как private в файл Swift, в котором он определен, и в этом случае он глобальный в лексической области, но ограниченный только для использования другим кодом в этом файле.

Расширения типа следуют тем же соображениям - ваши расширения по умолчанию internal к модулю, который их создает, и в его пространстве имен, поэтому существует небольшой риск конфликта.

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

+0

Похоже Swift вызывает внутреннюю функцию, если не указан модуль. Чтобы проверить это, в моем проекте приложения iPhone я определил глобальную функцию 'func print (text: String) {Swift.print (text +" * ")}' и назвал 'print (" test ")' при запуске приложения. Я не уверен, что произойдет, если вместо этого я включу тридцатипартийную структуру, которая определяет глобальную функцию 'print'. – ma11hew28

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