Programing

Swift에서 네임 스페이스를 사용하는 방법은 무엇입니까?

lottogame 2020. 6. 23. 07:41
반응형

Swift에서 네임 스페이스를 사용하는 방법은 무엇입니까?


설명서에는 중첩 형식 만 언급되어 있지만 네임 스페이스로 사용할 수 있는지 확실하지 않습니다. 네임 스페이스에 대한 명시 적 언급을 찾지 못했습니다.


Apple 개발자 포럼 에서 SevenTenEleven 님이 답변 함 :

네임 스페이스는 파일 단위가 아닙니다. 대상별로 설정되어 있습니다 ( "제품 모듈 이름"빌드 설정 기준). 따라서 다음과 같은 결과가 나타납니다.

import FrameworkA
import FrameworkB

FrameworkA.foo()

모든 Swift 선언은 일부 모듈의 일부로 간주되므로 " NSLog"(예, 여전히 존재) 라고 말하더라도 Swift가 " Foundation.NSLog" 로 생각하는 것을 얻습니다 .

또한 Chris Lattner 는 네임 스페이스에 대해 트윗했습니다 .

네임 스페이스는 Swift에 내재되어 있으며 모든 클래스 (등)는 내부에있는 모듈 (Xcode 대상)에 의해 내재적으로 범위가 지정됩니다. 클래스 접두사가 필요하지 않습니다.

내가 생각했던 것과 매우 다른 것 같습니다.


나는 스위프트의 이름이 감동적이라고 묘사 할 것이다. 그것은 지상에서 의미있는 현실에 해당하지 않는 많은 광고가 주어졌습니다.

예를 들어, WWDC 비디오는 가져 오는 프레임 워크에 MyClass 클래스가 있고 코드에 MyClass 클래스가있는 경우 "name mangling"이 다른 내부 이름을 제공하므로 해당 이름이 충돌하지 않는다고 설명합니다. 그러나 실제로는, 그들은 어떻게 자신의 코드의 MyClass의 승리는, 당신은 지정할 수 없습니다 "아니 아니, 난 프레임 워크에서 MyClass의 의미"한다는 의미에서, 충돌 - 말을 TheFramework.MyClass하지 작업 (컴파일러 당신이 무슨 뜻인지 알고 않습니다 그러나 프레임 워크에서 그러한 클래스를 찾을 수 없다고 말합니다).

내 경험에 따르면 Swift는 네임 스페이스가 가장 작습니다. 내 앱 중 하나를 Objective-C에서 Swift로 전환 할 때 매우 쉽고 멋진 임베디드 프레임 워크를 만들었습니다. 그러나 프레임 워크를 임포트하면 프레임 워크에있는 모든 Swift 컨텐츠를 임포트합니다. 따라서 다시 한 번, 네임 스페이스가 하나만 있고 글로벌입니다. 그리고 Swift 헤더가 없으므로 이름을 숨길 수 없습니다.

편집 : 시드 3 에서이 기능은 이제 다음과 같은 의미에서 온라인으로 제공되기 시작합니다. 기본 코드에 MyClass가 있고 프레임 워크 MyFramework에 MyClass가 있으면 전자가 기본적으로 후자를 어둡게하지만 프레임 워크에서 하나에 도달 할 수 있습니다 구문을 사용하여 MyFramework.MyClass. 따라서 우리는 실제로 별개의 네임 스페이스의 기초를 가지고 있습니다!

편집 2 : 시드 4에는 이제 액세스 제어가 있습니다! 또한 내 앱 중 하나에 임베디드 프레임 워크가 있으며 모든 것이 기본적으로 숨겨져 있으며 공개 API의 모든 비트를 명시 적으로 노출해야했습니다. 이것은 큰 개선입니다.


이것으로 약간의 실험을하면서 루트 "패키지"를 확장하여 자신의 파일에 이러한 "네임 스페이스"클래스를 만들었습니다. 이것이 모범 사례에 위배되는지 또는 내가 알 수있는 의미가 있는지 확실하지 않습니다 (?)

AppDelegate.swift

var n1 = PackageOne.Class(name: "Package 1 class")
var n2 = PackageTwo.Class(name: "Package 2 class")

println("Name 1: \(n1.name)")
println("Name 2: \(n2.name)")

PackageOne.swift

import Foundation

struct PackageOne {
}

패키지

import Foundation

struct PackageTwo {
}

PackageOneClass.swift

extension PackageOne {
    class Class {
        var name: String
        init(name:String) {
            self.name = name
        }
    }
}

PackageTwoClass.swift

extension PackageTwo {
    class Class {
        var name: String
        init(name:String) {
            self.name = name
        }
    }
}

편집하다:

위의 코드에서 "하위 패키지"를 생성하면 별도의 파일을 사용할 경우 작동하지 않는다는 것을 알았습니다. 어쩌면 누군가가 왜 그런지 암시 할 수 있습니까?

위의 파일을 추가 :

PackageOneSubPackage.swift

import Foundation

extension PackageOne {
    struct SubPackage {
    }
}

PackageOneSubPackageClass.swift

extension PackageOne.SubPackage {
    class Class {
        var name: String
        init(name:String) {
            self.name = name
        }
    }
}

Its throwing a compiler error: 'SubPackage' is not a member type of 'PackageOne'

If I move the code from PackageOneSubPackageClass.swift to PackageOneSubPackage.swift it works. Anyone?

Edit 2:

Fiddling around with this still and found out (in Xcode 6.1 beta 2) that by defining the packages in one file they can be extended in separate files:

public struct Package {
  public struct SubPackage {
    public struct SubPackageOne {
    }
    public struct SubPackageTwo {
    }
  }
}

Here are my files in a gist: https://gist.github.com/mikajauhonen/d4b3e517122ad6a132b8


I believe this is achieved using:

struct Foo
{
    class Bar
    {
    }
}

Then it can be accessed using:

var dds = Foo.Bar();

Swift uses modules much like in python (see here and here) and as @Kevin Sylvestre suggested you can also use the nested types as namespaces.

And to extend the answer from @Daniel A. White, in WWDC they were talking about the modules in swift.

Also here is explained:

Inferred types make code cleaner and less prone to mistakes, while modules eliminate headers and provide namespaces.


  • Namespaces are useful when you need to define class with the same name as class in existing framework.

  • Suppose your app has MyApp name, and you need to declare your custom UICollectionViewController.

You don't need to prefix and subclass like this:

class MAUICollectionViewController: UICollectionViewController {}

Do it like this:

class UICollectionViewController {} //no error "invalid redeclaration o..."

Why?. Because what you've declared is declared in current module, which is your current target. And UICollectionViewController from UIKit is declared in UIKit module.

How to use it within current module?

var customController = UICollectionViewController() //your custom class
var uikitController = UIKit.UICollectionViewController() //class from UIKit

How to distinguish them from another module?

var customController = MyApp.UICollectionViewController() //your custom class
var uikitController = UIKit.UICollectionViewController() //class from UIKit

In case anyone was curious, as of June 10th 2014, this is a known bug in Swift:

From SevenTenEleven

"Known bug, sorry! rdar://problem/17127940 Qualifying Swift types by their module name doesn't work."


You can use extension to use the mentioned structs approach for namespacing without having to indent all of your code towards the right. I've been toying with this a bit and I'm not sure I'd go as far as creating Controllers and Views namespaces like in the example below, but it does illustrate how far it can go:

Profiles.swift:

// Define the namespaces
struct Profiles {
  struct Views {}
  struct ViewControllers {}
}

Profiles/ViewControllers/Edit.swift

// Define your new class within its namespace
extension Profiles.ViewControllers {
  class Edit: UIViewController {}
}

// Extend your new class to avoid the extra whitespace on the left
extension Profiles.ViewControllers.Edit {
  override func viewDidLoad() {
    // Do some stuff
  }
}

Profiles/Views/Edit.swift

extension Profiles.Views {
  class Edit: UIView {}
}

extension Profiles.Views.Edit {
  override func drawRect(rect: CGRect) {
    // Do some stuff
  }
}

I haven't used this in an app since I haven't needed this level of separation yet but I think it's an interesting idea. This removes the need for even class suffixes such as the ubiquitous *ViewController suffix which is annoyingly long.

However, it doesn't shorten anything when it's referenced such as in method parameters like this:

class MyClass {
  func doSomethingWith(viewController: Profiles.ViewControllers.Edit) {
    // secret sauce
  }
}

참고URL : https://stackoverflow.com/questions/24002821/how-to-use-namespaces-in-swift

반응형