Я пытаюсь понять самый первый пример Elm и имеет следующее:
import Graphics.Element exposing (..)
Что означает exposing (..)
?
Я пытаюсь понять самый первый пример Elm и имеет следующее:
import Graphics.Element exposing (..)
Что означает exposing (..)
?
Экспозиция (..) позволяет вам напрямую вызвать функцию. Например, если SamplePackage имеет функции x и y, import SamplePackage
позволит вам вызвать SamplePackage.x и SamplePackage.y, тогда как
import SamplePackage exposing (..)
позволит вам вызывать x и y без указания их содержащего пакета.
Это означает, что вы можете получить доступ ко всему непосредственно в модуле Graphics.Element, не указав сначала пакет. Поскольку в этом примере используются только "show" и "Element", вы можете изменить строку импорта на:
import Graphics.Element exposing (Element, show)
И это все равно будет работать для этого примера.
Это старый вопрос, но я все равно отвечу другим, чтобы подумать о exposing (..)
, и немного объясню, почему это обычно плохая идея. Если у вас есть опыт программирования на Python, вы можете думать об этом как о from module import *
в Python. Этот Код Elm:
import Graphics.Element exposing (Element, show)
будет выглядеть так в Python:
from Graphics.Element import Element, show
тогда как этот Код Elm:
import Graphics.Element exposing (..)
будет выглядеть так в Python:
from Graphics.Element import *
Первые два будут только добавлять имена Element
и show
в ваше текущее пространство имен модулей; последние два примера добавят все имена из Graphics.Element
в ваше пространство имен. Это удобно, когда вы впервые пишете свой модуль, поскольку вы еще не знаете, какие имена вам понадобятся от Graphics.Element
. Но как только вы закончите писать свой модуль, целесообразно вернуться и изменить exposing (..)
на exposing (just, the, names, you, need)
. Таким образом, вы можете быть уверены, что не столкнетесь с именами позже.
В качестве примера того, как конфликты имен могут быть плохими, скажем, вы пишете модуль с именем myGraphics
, в котором вы создаете функцию с именем rotatedImage
, потому что она не (в настоящее время) в Graphics.Element
. Но в дальнейшем Graphics.Element
добавляет функцию rotatedImage
с тонко различной семантикой (например, ваша функция использует градусы, но "официальная" функция использует радианы). Теперь есть две функции rotatedImage
, которые доступны вашему коду... и вы можете легко покончить с собой:
{- someOtherModule.elm -}
import Graphics.Element exposing (..)
{- ... more code ... -}
someImage = rotatedImage (pi / 2) sourceImage -- Angle is in radians
Теперь вам нужна другая функция из вашего модуля myGraphics
, поэтому вы импортируете его:
{- someOtherModule.elm -}
import Graphics.Element exposing (..)
import myGraphics exposing (..)
{- ... more code ... -}
someImage = rotatedImage (pi / 2) sourceImage -- WHOOPS, angle is now in degrees!
И вдруг вращение someImage
изменилось! Когда вы импортировали myGraphics
, намеревались ли вы изменить способ отображения someImage
на вашей странице? Почти наверняка нет.
Это, почему import Foo exposing (..)
следует избегать, если ваш код относительно стабилен. Это очень полезно в разработке, так как вам не нужно постоянно возвращаться к началу вашего кода, чтобы добавить другое имя в ваш оператор import
. Но как только вы закончите делать тяжелую разработку на своем модуле, и вы вносите в него какие-то редкие изменения, вы действительно должны переключиться на использование import Foo exposing (just, the, names, you, need)
. Таким образом вы уклонитесь от многих ловушек.