Dokümantasyon sadece iç içe tiplerden bahsediyor, ancak isim alanı olarak kullanılıp kullanılamayacakları belli değil. İsim alanlarından açıkça bahsetmedim.
Dokümantasyon sadece iç içe tiplerden bahsediyor, ancak isim alanı olarak kullanılıp kullanılamayacakları belli değil. İsim alanlarından açıkça bahsetmedim.
Yanıtlar:
Tarafından Cevaplanan SevenTenEleven içinde Apple dev forumun :
Ad alanları dosya başına değildir; bunlar hedef başınadır ("Ürün Modülü Adı" oluşturma ayarını temel alır). Böylece şöyle bir şey elde edersiniz:
import FrameworkA import FrameworkB FrameworkA.foo()
Tüm Swift bildirimleri bazı modüllerin bir parçası olarak kabul edilir, bu nedenle "
NSLog
" (evet, hala var) derken Swift'in "Foundation.NSLog
" olarak düşündüğünü görürsünüz .
Ayrıca Chris Lattner isim boşluğunu tweetledi .
Ad boşluğu Swift'te örtüktür, tüm sınıflar (vb.) İçinde bulundukları modül (Xcode hedefi) tarafından dolaylı olarak kapsamlandırılır. Sınıf öneklerine gerek yoktur
Düşündüğümden çok farklı görünüyor.
forums.developer.apple.com
maalesef yeni forumlar sitesine aktarmadı.
Swift'in ad boşluğunu aspirasyon olarak tarif ederdim; yerdeki anlamlı gerçekliğe karşılık gelmeyen birçok reklam verildi.
Örneğin, WWDC videoları içe aktardığınız bir çerçevede bir Sınıf MyClass varsa ve kodunuzda bir Sınıf MyClass varsa, "ad yönetimi" onlara farklı dahili adlar verdiğinden, bu adlar çakışmaz. Gerçekte, ancak, bunu kendi kodun Sınıfım kazanç ve belirleyemezsiniz "Hayır hayır, ben çerçevesinde Sınıfım demek" anlamında, çatışma - diyerek TheFramework.MyClass
değil işi (derleyici ne demek istediğini bilir yapar , ancak çerçevede böyle bir sınıf bulamadığını söylüyor).
Benim tecrübem, Swift'in en ufak bir isimde yer almaması. Uygulamalarımdan birini Objective-C'den Swift'e dönüştürürken gömülü bir çerçeve oluşturdum çünkü yapmak çok kolay ve havalıydı. Bununla birlikte, çerçeveyi içe aktarmak, çerçevedeki tüm Swift öğelerini içe aktarır - bu yüzden presto, bir kez daha sadece bir ad alanı vardır ve küreseldir. Ve Swift üstbilgileri yok, bu yüzden herhangi bir ismi gizleyemezsiniz.
DÜZENLEME: 3. tohumda, bu özellik şu anda çevrimiçi olmaya başlıyor, aşağıdaki anlamda: ana kodunuz MyClass içeriyorsa ve çerçeveniz MyFramework MyClass içeriyorsa, ilki varsayılan olarak ikincisini gölgede bırakır, ancak çerçevede bu özelliğe erişebilirsiniz sözdizimini kullanarak MyFramework.MyClass
. Böylece aslında farklı bir isim alanının ilkelerine sahibiz!
EDIT 2: Tohum 4'te artık erişim kontrollerimiz var! Ayrıca, uygulamalarımdan birinde gömülü bir çerçevem var ve yeterince eminim, her şey varsayılan olarak gizlendi ve herkese açık API'nın tüm bitlerini açıkça ortaya koymak zorunda kaldım. Bu büyük bir gelişme.
Foundation.NSArray
.
Bu konuda bazı deneyler yaparken kök "paket" genişleterek kendi dosyalarında bu "ad alanı" sınıfları oluşturmak sona erdi. Bunun en iyi uygulamalara aykırı olup olmadığından emin değilim ya da herhangi bir etkisi olup olmadığından emin değilim (?)
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 {
}
PackageTwo.swift
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
}
}
}
Düzenle:
Sadece yukarıdaki kodda "alt paketler" oluşturmanın ayrı dosyalar kullanırsanız işe yaramayacağını öğrendim. Belki birisi neden böyle olabileceğine dair ipucu verebilir?
Yukarıdakilere aşağıdaki dosyaları ekleme:
PackageOneSubPackage.swift
import Foundation
extension PackageOne {
struct SubPackage {
}
}
PackageOneSubPackageClass.swift
extension PackageOne.SubPackage {
class Class {
var name: String
init(name:String) {
self.name = name
}
}
}
Derleyici hatası veriyor: 'SubPackage', 'PackageOne' üyesi değil
Kodu PackageOneSubPackageClass.swift 'den PackageOneSubPackage.swift' e taşırsam çalışır. Kimse?
Düzenleme 2:
Bu hareketin etrafında dolaşmak ve (Xcode 6.1 beta 2'de) paketleri tek bir dosyada tanımlayarak ayrı dosyalarda genişletilebileceklerini keşfetti:
public struct Package {
public struct SubPackage {
public struct SubPackageOne {
}
public struct SubPackageTwo {
}
}
}
İşte dosyalarımın bir özeti: https://gist.github.com/mikajauhonen/d4b3e517122ad6a132b8
Bunun kullanılarak elde edildiğine inanıyorum:
struct Foo
{
class Bar
{
}
}
Ardından şunlara erişilebilir:
var dds = Foo.Bar();
enum
a değil, kullanırsınız struct
, bu nedenle a'yı başlatamazsınız Foo
.
Swift, python'daki gibi modülleri kullanır ( buraya ve buraya bakın ) ve @Kevin Sylvestre'nin önerdiği gibi , iç içe türleri ad alanları olarak da kullanabilirsiniz .
Ve @Daniel A. White'ın cevabını genişletmek için WWDC'de hızlı bir şekilde modüller hakkında konuşuyorlardı.
Ayrıca burada açıklanmaktadır:
Çıkarılan türler kodu daha temiz ve hatalara daha az eğilimli hale getirirken, modüller başlıkları ortadan kaldırır ve ad alanları sağlar.
Ad alanları, mevcut çerçevede sınıfla aynı ada sahip bir sınıf tanımlamanız gerektiğinde yararlıdır .
Uygulamanızın
MyApp
adı olduğunu ve özelliğinizi beyan etmeniz gerektiğini varsayalımUICollectionViewController
.
Bunun gibi ön ek ve alt sınıflar eklemenize gerek yoktur :
class MAUICollectionViewController: UICollectionViewController {}
Şöyle yapın:
class UICollectionViewController {} //no error "invalid redeclaration o..."
Neden? . Çünkü beyan ettiğiniz , mevcut hedefiniz olan geçerli modülde bildirilir . Ve gelen bildirilmiştir modülü.UICollectionViewController
UIKit
UIKit
Mevcut modülde nasıl kullanılır?
var customController = UICollectionViewController() //your custom class
var uikitController = UIKit.UICollectionViewController() //class from UIKit
Onları başka bir modülden nasıl ayırt edebilirim?
var customController = MyApp.UICollectionViewController() //your custom class
var uikitController = UIKit.UICollectionViewController() //class from UIKit
Sen kullanabilirsiniz extension
sözü kullanmak struct
sağa doğru tüm kodu girinti zorunda kalmadan ad alanı için yaklaşımını. Bununla biraz oynuyorum Controllers
ve Views
aşağıdaki örnekte olduğu gibi oluşturma ve ad alanları kadar ileri gideceğimden emin değilim , ancak ne kadar ileri gidebileceğini gösteriyor:
Profiller. Kaydırma :
// Define the namespaces
struct Profiles {
struct Views {}
struct ViewControllers {}
}
Profiller / 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
}
}
Profiller / Görüntüleme / Edit.swift
extension Profiles.Views {
class Edit: UIView {}
}
extension Profiles.Views.Edit {
override func drawRect(rect: CGRect) {
// Do some stuff
}
}
Henüz bu ayrılma düzeyine ihtiyaç duymadığım için bunu bir uygulamada kullanmadım ama bence ilginç bir fikir. Bu, rahatsız edici derecede uzun olan her yerde bulunan * ViewController soneki gibi sınıf eklerine bile olan ihtiyacı ortadan kaldırır.
Ancak, bu gibi yöntem parametrelerinde olduğu gibi referans alındığında hiçbir şeyi kısaltmaz:
class MyClass {
func doSomethingWith(viewController: Profiles.ViewControllers.Edit) {
// secret sauce
}
}
Birisinin merak etmesi durumunda, 10 Haziran 2014'ten itibaren bu Swift'te bilinen bir hatadır:
Gönderen SevenTenEleven
"Bilinen bir hata, özür dilerim! Rdar: // problem / 17127940 Swift türlerini modül adlarına göre çalışmaz."