programing

Swift에서 네임스페이스를 사용하는 방법

topblog 2023. 4. 18. 21:41
반응형

Swift에서 네임스페이스를 사용하는 방법

문서에서는 중첩된 유형만 언급하고 있지만 네임스페이스로 사용할 수 있는지 여부는 명확하지 않습니다.네임스페이스에 대한 명확한 언급은 못 찾았습니다.

나는 Swift의 네임스페이스가 포부적인 것이라고 묘사하고 싶다; 그것은 현장에서의 어떠한 의미있는 현실과도 일치하지 않는 많은 광고를 제공해 왔다.

예를 들어, WWDC 비디오에는 Import하는 프레임워크에 MyClass 클래스가 있고 코드에 MyClass 클래스가 있는 경우 "이름 망글링"으로 인해 서로 다른 내부 이름이 제공되므로 이러한 이름이 충돌하지 않는다고 나와 있습니다.그러나 실제로는 자신의 코드의 MyClass가 이기므로 "No, MyClass in the Framework"를 지정할 수 없습니다.TheFramework.MyClass동작하지 않습니다(컴파일러는 무슨 뜻인지 알지만 프레임워크에서는 그런 클래스를 찾을 수 없다고 합니다).

제 경험으로는 Swift는 전혀 이름이 오르지 않습니다.앱 중 하나를 Objective-C에서 Swift로 바꾸면서 임베디드 프레임워크를 만들었습니다.왜냐하면 너무 쉽고 멋졌기 때문입니다.그러나 프레임워크를 Import하면 프레임워크 내의 모든 Swift가 Import됩니다.따라서 다시 한 번 말씀드리지만 네임스페이스는 1개뿐이고 글로벌합니다.또한 Swift 헤더는 없으므로 이름을 숨길 수 없습니다.

편집: 시드 3에서 이 기능은 온라인 상태가 되었습니다.메인코드에 MyClass가 포함되어 있고 프레임워크에 MyFramework가 포함되어 있는 경우, 디폴트로 후자가 가려지지만, 구문을 사용하여 프레임워크에 접속할 수 있습니다.MyFramework.MyClass이렇게 해서 우리는 사실상 다른 네임스페이스의 기초를 가지고 있다!

편집 2: 시드 4에서는 액세스 제어가 가능해졌습니다!게다가 제 앱 중 하나에는 임베디드 프레임워크가 있는데, 당연히 모든 것이 기본적으로 숨겨져 있어서 공개 API의 모든 부분을 명시적으로 공개해야 했습니다.이것은 큰 발전입니다.

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

네임스페이스는 파일별이 아니라 대상별("제품 모듈 이름" 빌드 설정에 기반)입니다.결국 이렇게 되는 거죠.

import FrameworkA
import FrameworkB

FrameworkA.foo()

Swift 은 일부에 "Swift"라고 "Swift"라고할 수 .NSLog스위프트가 '스위프트를 '스위프트'라고 .Foundation.NSLog".".".".

또한 Chris Ratner는 네임스페이스에 대해 트위터를 했다.

네임스페이스는 Swift에서 암묵적으로 사용됩니다.모든 클래스(등)는, 소속하는 모듈(Xcode 타겟)에 의해서 암묵적으로 스코핑 됩니다.클래스 프리픽스는 필요 없습니다.

내가 생각했던 것과는 많이 다른 것 같아.

이 실험을 하는 동안 루트 패키지(package)를 확장하여 파일 내에 이러한 이름 기반 클래스를 만들었습니다.이것이 베스트 프랙티스에 어긋나는 것인지, 또는 내가 모르는 영향이 있는 것인지(?) 확실하지 않다.

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)")

Package One.swift

import Foundation

struct PackageOne {
}

PackageTwo.swift

import Foundation

struct PackageTwo {
}

Package OneClass.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
        }
    }
}

컴파일러 오류 발생: 'SubPackage'는 'PackageOne' 멤버 유형이 아닙니다.

PackageOneSubPackageClass.swift에서 PackageOneSubPackage.swift로 코드를 이동하면 동작합니다.누구라도 있나요?

편집 2:

이것을 만지작거리다가 (Xcode 6.1 베타 2) 패키지를 1개의 파일로 정의함으로써 다른 파일로 확장할 수 있다는 것을 알게 되었습니다.

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

다음은 제 파일입니다.https://gist.github.com/mikajauhonen/d4b3e517122ad6a132b8

이것은, 다음의 방법으로 실현된다고 생각합니다.

struct Foo
{
    class Bar
    {
    }
}

다음으로, 다음의 방법으로 액세스 할 수 있습니다.

var dds = Foo.Bar();
  • 네임스페이스는 기존 프레임워크에서 클래스와 동일한 이름으로 클래스를 정의해야 할 때 유용합니다.

  • Suppose your app has 사용하시는 앱에MyApp name, and you need to declare your custom 커스텀을 선언해야 합니다.UICollectionViewController.

다음과 같이 프리픽스와 서브클래스를 지정할 필요는 없습니다.

class MAUICollectionViewController: UICollectionViewController {}

다음과 같이 합니다.

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

왜냐고요? 당신이 선언한 것이 현재 목표인 현재 모듈에서 선언되었기 때문입니다.그리고.UICollectionViewController부에서UIKit is declared in 에 선언되어 있다.UIKit모듈.모듈.

현재 모듈 내에서 사용하는 방법

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

다른 모듈과 구별하는 방법

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

Swift는 python(여기와 여기참조)과 같은 모듈을 사용하며 @Kevin Sylvestre가 제안하는 것처럼 네스트된 유형을 네임스페이스로도 사용할 수 있습니다.

그리고 @Daniel A에서 답변을 연장합니다.화이트, WWDC에서 그들은 모듈에 대해 빠르게 이야기하고 있었다.

, 이하에 대해서도 설명합니다.

추론 유형을 사용하면 코드가 깔끔해지고 오류가 발생하기 쉬우며 모듈은 헤더를 삭제하고 네임스페이스를 제공합니다.

사용할 수 있습니다.extension상술한 바와 같이struct모든 코드를 오른쪽으로 들여쓰지 않고 네임스페이스를 사용할 수 있습니다.내가 이걸 가지고 장난을 쳤는데, 내가 이 모든 것들을 만들어 낼 수 있을지 모르겠어.Controllers그리고.Views다음 예시와 같이 네임스페이스가 얼마나 멀리 갈 수 있는지를 보여줍니다.

Profiles.swift:

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

프로파일/ViewController/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
  }
}

프로파일/뷰/Edit.swift

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

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

아직 이 정도의 분리가 필요 없기 때문에 앱에서는 사용하지 않았지만, 재미있는 아이디어라고 생각합니다.이것에 의해, 유비쿼터스 *ViewController 서픽스등의 클래스 서픽스가 불필요하게 됩니다.

단, 다음과 같은 메서드 파라미터에서 참조되는 경우에는 단축되지 않습니다.

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

Framework and Libraries를 사용하여 네임스페이스를 구현할 수 있지만 가장 좋은 해결책은 Swift Package Manager를 사용하여 로컬 패키지를 사용하는 것입니다.이 접근 방식에는 액세스 수식자가 있는 것 외에 몇 가지 이점이 있습니다.Swift Package Manager에서와 같이 파일은 타겟 멤버쉽이 아닌 디렉토리 시스템에 기반하여 관리되므로 팀워크에서 자주 발생하는 머지 컨플릭트에 시달릴 필요가 없습니다.또, 파일 멤버쉽을 설정할 필요도 없습니다.

로컬 Swift 패키지의 사용 방법에 대해서는, 다음의 링크를 참조해 주세요:Organizing Your Code with Local Packages

2014년 6월 10일 현재 Swift에서 알려진 버그는 다음과 같습니다.

세븐텐일레븐에서

"알려진 버그입니다.죄송합니다!rdar://problem/17127940 모듈 이름으로 Swift 유형을 한정하는 것이 작동하지 않습니다."

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

반응형