설명서에는 중첩 형식 만 언급되어 있지만 네임 스페이스로 사용할 수 있는지 확실하지 않습니다. 네임 스페이스에 대한 명시 적 언급을 찾지 못했습니다.
설명서에는 중첩 형식 만 언급되어 있지만 네임 스페이스로 사용할 수 있는지 확실하지 않습니다. 네임 스페이스에 대한 명시 적 언급을 찾지 못했습니다.
답변:
Apple dev 포럼 에서 SevenTenEleven 님이 답변 함 :
네임 스페이스는 파일 단위가 아닙니다. 대상별로 설정되어 있습니다 ( "제품 모듈 이름"빌드 설정 기준). 따라서 다음과 같은 결과가 나타납니다.
import FrameworkA import FrameworkB FrameworkA.foo()
모든 Swift 선언은 일부 모듈의 일부로 간주되므로 "
NSLog
"(예, 여전히 존재 함) 라고 말하더라도 Swift가 "Foundation.NSLog
" 로 생각하는 것을 얻습니다 .
또한 Chris Lattner 는 네임 스페이스에 대해 트윗했습니다 .
네임 스페이스는 Swift에 내재되어 있으며 모든 클래스 (등)는 내부에있는 모듈 (Xcode 대상)에 의해 내재적으로 범위가 지정됩니다. 클래스 접두사가 필요하지 않습니다.
내가 생각했던 것과는 매우 다른 것 같습니다.
forums.developer.apple.com
, 불행히도 Apple은 해당 스레드를 새 포럼 사이트 로 가져 오지 않았습니다 .
나는 스위프트의 이름이 감동적이라고 묘사 할 것이다. 그것은 지상에서 의미있는 현실에 해당하지 않는 많은 광고가 주어졌습니다.
예를 들어, WWDC 비디오는 가져 오는 프레임 워크에 MyClass 클래스가 있고 코드에 MyClass 클래스가있는 경우 "name mangling"이 다른 내부 이름을 제공하므로 해당 이름이 충돌하지 않는다고 명시되어 있습니다. 그러나 실제로는, 그들은 어떻게 자신의 코드의 MyClass의 승리는, 당신은 지정할 수 없습니다 "아니 아니, 난 프레임 워크에서 MyClass의 의미"한다는 의미에서, 충돌 - 말을 TheFramework.MyClass
하지 작업 (컴파일러 당신이 무슨 뜻인지 알고 않습니다 그러나 프레임 워크에서 그러한 클래스를 찾을 수 없다고 말합니다.
내 경험에 따르면 Swift는 네임 스페이스가 가장 작습니다. 내 앱 중 하나를 Objective-C에서 Swift로 전환 할 때 매우 쉽고 멋진 임베디드 프레임 워크를 만들었습니다. 그러나 프레임 워크를 임포트하면 프레임 워크에있는 모든 Swift 컨텐츠를 임포트합니다. 따라서 다시 한 번, 네임 스페이스가 하나만 있고 글로벌입니다. 그리고 Swift 헤더가 없으므로 이름을 숨길 수 없습니다.
편집 : 시드 3 에서이 기능은 이제 다음과 같은 의미에서 온라인으로 제공되기 시작합니다. 기본 코드에 MyClass가 있고 프레임 워크 MyFramework에 MyClass가 있으면 전자가 기본적으로 후자를 어둡게하지만 프레임 워크에서 하나에 도달 할 수 있습니다 구문을 사용하여 MyFramework.MyClass
. 따라서 우리는 실제로 별개의 네임 스페이스의 기초를 가지고 있습니다!
편집 2 : 시드 4에는 이제 액세스 제어가 있습니다! 또한 내 앱 중 하나에 임베디드 프레임 워크가 있으며 모든 것이 기본적으로 숨겨져 있으며 공개 API의 모든 비트를 명시 적으로 노출해야했습니다. 이것은 큰 개선입니다.
Foundation.NSArray
.
이것으로 약간의 실험을하면서 루트 "패키지"를 확장하여 자신의 파일에 이러한 "네임 스페이스"클래스를 만들었습니다. 이것이 모범 사례에 위배되는지 또는 내가 알 수있는 의미가 있는지 확실하지 않습니다 (?)
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
}
}
}
컴파일러 오류가 발생합니다 : 'SubPackage'는 'PackageOne'의 멤버 유형이 아닙니다.
PackageOneSubPackageClass.swift에서 PackageOneSubPackage.swift로 코드를 이동하면 작동합니다. 누군가?
편집 2 :
이 문제를 해결하면서 (Xcode 6.1 베타 2에서) 하나의 파일에 패키지를 정의하면 별도의 파일로 확장 할 수 있음을 알았습니다.
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();
enum
아닌를 struct
당신이 인스턴스화 할 수 있도록 Foo
.
Swift는 파이썬과 매우 유사한 모듈을 사용하며 ( 여기 및 여기 참조 ) @Kevin Sylvestre가 제안한 것처럼 중첩 유형을 사용할 수도 있습니다 것처럼 을 네임 스페이스로 .
그리고 @Daniel A. White의 답변을 확장하기 위해 WWDC에서 그들은 모듈에 대해 신속하게 이야기했습니다.
또한 여기 에 설명되어 있습니다 :
유추 된 형식은 코드를 더 깨끗하고 실수가 덜 발생하는 반면 모듈은 헤더를 제거하고 네임 스페이스를 제공합니다.
네임 스페이스는 기존 프레임 워크의 클래스 와 이름 이 같은 클래스를 정의해야 할 때 유용합니다 .
앱에
MyApp
이름이 있고 custom을 선언해야 한다고 가정하십시오UICollectionViewController
.
다음 과 같이 접두사와 하위 클래스를 지정할 필요가 없습니다 .
class MAUICollectionViewController: UICollectionViewController {}
다음과 같이하십시오 :
class UICollectionViewController {} //no error "invalid redeclaration o..."
왜? . 당신이 선언 선언 한 일 때문에 현재 모듈 입니다, 당신의 현재 대상 . 그리고 UICollectionViewController
from UIKit
은 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
오른쪽으로 모든 코드를 들여 쓰지 않고도 네임 스페이스에 대해 extension
언급 된 struct
접근 방식 을 사용할 수 있습니다 . 나는 이것을 조금 가지고 놀았고 아래 예제와 같이 네임 스페이스 Controllers
와 Views
네임 스페이스 를 만들지 확실 하지 않지만 얼마나 멀리 갈 수 있는지 보여줍니다.
Profiles.swift :
// Define the namespaces
struct Profiles {
struct Views {}
struct ViewControllers {}
}
프로파일 /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
}
}
프로필 / 뷰 / 편집 .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
}
}
2014 년 6 월 10 일 현재 궁금한 점이 있으면 Swift의 알려진 버그입니다.
에서 SevenTenEleven
"알려진 버그, 죄송합니다. rdar : // problem / 17127940 해당 Swift 유형의 모듈 이름으로 작동하지 않습니다."