Is it possible to import just one class from a Swift module? I used
import struct Foundation.Date
but now, NSString and other Foundation classes/structs are available too, at the top level!
All I really want is the Date class, to avoid polluting the namespace.
This answer is originally made for objective-c but the behaviour is the same: Why does a simple program import <Foundation/Foundation.h> instead of individual header files?
You don't have to worry about that, I think your compiler do this job perfectly ! :)
Related
I'm still a newbie to swift and I can't get a clear answer on a couple things.
So far I've just been using a single file in playgrounds.
If I want to use more files, how can I access data (variables and functions) from classes created there in my main file that controls the view?
From what I understand having multiple files would just be for convenience so I don't have could to write it again.
(Also on the side) what does it mean when a function has private, public or just 'func'?
I'm using swift 3 playgrounds
Thanks
Making things public will make them importable from other modules. Making it private will make it only accessible by methods within its containing scope (encapsulation). For code that lives at the top level, this scope is the entire .swift file it lives in. Without either access modifier (just bare “func”), your thing will default to internal, which means it is accessible from any other code within the same module, but not by code in a different module.
A special case is the fileprivate modifier which restricts access to the .swift file the code lives in. For code that does not live in a class or struct, this does the exact same thing as private. Some Swift designers discourage use of this modifier, and it may be removed in future versions of Swift.
There is a fifth access modifier in Swift, open, which does the exact same thing as public, except it also allows subclassing, and only applies to classes. This one is rarely used, but useful for certain library interfaces.
To import all the public symbols in a module, use
import Module
To import a single public symbol, use
import var Module.variable
import func Module.function
import struct Module.structure
import class Module.class
...
I'm learning java and I'm told this package is provided by default, to every class, because its methods are so common. I thought I would try to import it, any way to see what would happen. I know its not practical and probably expensive but I'm curious as to why it's doesn't work from a technical point of view.
import javax.lang.*;//why doesn't this work.
javax.lang contains only a single package: model
https://docs.oracle.com/javase/7/docs/api/index.html?javax/lang/model/package-summary.html
you're not doing anything by importing this package. Maybe you're confusing it with java.lang ?
You don't need to import java.lang.*
There is one exception to the import rule. All classes in the java.lang package are imported by default. Thus you do not need to import java.lang.*; to use them without fully qualified names.
Consider the System.out.println() method we've been using since the first day of class.
System is really the java.lang.System class. This class has a public static field called out which is an instance of the java.io.PrintStream class. So when you write System.out.println(), you're really calling the println() method of the out field of the java.lang.System class.
In c# when pulling in a library that has a lot of name collisions with existing code, there's a way to alias the import so you don't need to fully clarify the namespace for each use. eg:
using MyCompany.MyLibrary.Model as MMM
then you could do
MMM.MyObject
instead of
MyCompany.MyLibrary.Model.MyObject
With the recent update to swift 3.0, I've found some of my model objects are now colliding with the Foundation types, and I've been forced to prefix things that used to have an NS prefix in the class name with Foundation.classname. It would be great if I could type alias the import of my model library much like the c# example given above. Is this possible in swift 3.0? If not is there another strategy to avoid name collisions that would result in having to write the framework name in front of each type? I'm considering going back to prefixing my class names like we did in obj-c, but I'm trying to explore my options before I do that.
Update 2021 for Swift 5;
No, but you can import all and alias (in separate file), read below for more details.
Generally
You can import a particular entity as well as the entire module:
import struct SomeModule.SomeStruct
import class SomeModule.SomeClass
import func SomeModule.someFunc
See the full list of "importable" entity types in the import-kind rule of Swift grammar.
Then you can create a typealias:
typealias SMSomeStruct = SomeModule.SomeStruct
And, as of Swift 3, there is no import declaration combined with aliasing.
Considering the Collisions with Foundation Entities
Say, you have a class SomeModule.NumberFormatter.
It is enough to create two typealiases in a separate Swift file (in an importing project) to prevent collisions:
import Foundation
import SomeModule
typealias NumberFormatter = Foundation.NumberFormatter
typealias SMNumberFormatter = SomeModule.NumberFormatter
It's not even with Swift 5 possible to directly alias an import-statement!?
But fortunately, I could workaround it with something like:
import typealias MyModule.MyInnerClass
I mean, if we are the module's developer, simply move the alias into the module, like:
public typealias MyInnerClass = MyClass.MyInnerClass
public class MyClass {
public class MyInnerClass {
// Some cool logic here...
}
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
#class vs. #import
I am Really confused with this,Whats the difference between writing #classname & #import"classname.h" .When Do we go for #classname?
You can find a good answer here and in the Objective-C Programming Language documentation on ADC
#classname is a forward declaration. Nothing gets imported, it just informes the compiler, that the class will exist on runtime.
#import will actually import the other class -> you can imagine it as a copy it into the file. so the imported classes will get compiled before the one, that it is written in.
The #classname just let's the compiler know that the class exists however you'll still need to import the corresponding .h. You can use the #classname in the .h and then import the class in the .m and this will allow you to avoid circular references. You can read more about it here Apple Docs
#className directive is introduced to overcome cyclic reference of classes, it is also known as Forward Declaration
#class will just inform the compiler that there is a class named "#className yourClass" no need to worry about that class and in runtime it just refer that class and executes.
#import "className" will keep a copy of that particular class.
#classname just tells the compiler that the class classname exists.
#import really imports the header file so that the compiler not only knows that it exists, but also how it looks. (like ivars, methods etc...)
I know that the convention is to do any kind of header in your .m. However, what if I need to import something so that I can have access to the protocol? Say I have a class Test.h/m and I have a protocol called TestProtocol that another class say, MyTest.h wants to implement. What I usually do in this case is to import Test.h in MyTest.h class file. I find this a bit distracting, is there a way to avoid this? What are some cases when this is fine?
You can put the protocol in it's own TestProtocol.h and import that in MyTest.h.
This is the way I do it for delegate protocols etc.
You can define the TestProtocol protocol in a separate TestProtocol.h file that you import wherever you want, or you can use a forward protocol declaration
#protocol TestProtocol;
There is no rule that says a .h file has to have a corresponding .m file.
So you could declare your protocol in TestProtocol.h and import that wherever it's needed.