In the Advanced Swift talk, the generated code for an for loop is described as:
var __g: Generator = mySequence.generate()
while let x = __g.next() {
// iterations here
}
Does the underscore prefix have some specific meaning?
No, the underscore- and double-underscore-prefixes have no specific meaning in Swift. They conventionally imply "private" or "internal" declarations, but you can define variables beginning with as many underscores as you like.
Related
I'm trying to create my own custom operator !!
postfix operator !! //error
static postfix func !! (optionalValue: Optional<T>) -> T {
// realisation
}
I get error message
Expected operator name in operator declaration
in the declarations.
Only a restricted set of characters can be used for custom operators, and some operators are reserved and cannot be overloaded.
The precise rules are documented in Lexical Structure. In particular (emphasis added):
Although you can define custom operators that contain a question mark (?), they can’t consist of a single question mark character only. Additionally, although operators can contain an exclamation mark (!), postfix operators can’t begin with either a question mark or an exclamation mark.
Also
your operator is generic, so you have to declare T as the placeholder type with <T>,
the function must not be static unless defined inside a type.
Working example:
postfix operator =!!
postfix func =!! <T> (optionalValue: Optional<T>) -> T {
// realization
}
Here is an example
//Define a operator
prefix operator √
//create a function and perform the operation.
prefix func √(lhs: Double) -> Double {
return sqrt(lhs)
}
//Do operation
let someVal:Double = 25
let squareRoot = √someVal // result is 5
I was browsing Alamofire sources and found a variable name that is backtick escaped in this source file
open static let `default`: SessionManager = {
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = SessionManager.defaultHTTPHeaders
return SessionManager(configuration: configuration)
}()
However in places where variable is used there are no backticks. What's the purpose of backticks?
Removing the backticks results in the error:
Keyword 'default' cannot be used as an identifier here
According to the Swift documentation :
To use a reserved word as an identifier, put a backtick (`)before and after it. For example, class is not a valid identifier, but `class` is valid. The backticks are not considered part of the identifier; `x` and x have the same meaning.
In your example, default is a Swift reserved keyword, that's why backticks are needed.
Example addendum to the accepted answer, regarding using reserved word identifiers, after they have been correctly declared using backticks.
The backticks are not considered part of the identifier; `x` and x
have the same meaning.
Meaning we needn't worry about using the backticks after identifier declaration (however we may):
enum Foo {
case `var`
case `let`
case `class`
case `try`
}
/* "The backticks are not considered part of the identifier;
`x` and x have the same meaning" */
let foo = Foo.var
let bar = [Foo.let, .`class`, .try]
print(bar) // [Foo.let, Foo.class, Foo.try]
Simply put, by using backticks you are allowed to use
reserved words for variable names etc.
var var = "This will generate an error"
var `var` = "This will not!"
I am learning swift using learnxinyminutes.com
I'm having a hard time understanding a component of on of the examples on the site (below), namely the use of underscore in the let statements instead of variable names.
// Variadic Args
func setup(numbers: Int...) {
let _ = numbers[0]
let _ = numbers.count
}
I understand that swift wants you to use underscore if you never declare the variable, but 1) why would you want to declare variables you never use? And 2) is there a way to get those values out if you used _. And, 3) if so, how?
1) why would you want to declare variables you never use?
Generally you don't! There are some cases though where you might want to, such as the example Danny Buonocore gave. Another example might be this: say you want to check that a variable is non-nil before you do something, though you do not need that variable for the subsequent code. (A guard statement is probably more useful in these situations).
if let _ = titleString {
// Do something that doesn't use titleString, but where it being non-nil means this operation is valid
}
Another example is with Swift functions. Names for a second, third, etc. parameter must be identified whenever calling a function. For example:
func externalizedParameters(first: Int?, second: Int?) {
...
}
Which is called using externalizedParameters(5, second: 6).
But if you are doing something trivial, and the function name already makes it clear what the two parameters are, such as with a swap operation, you might not want to force the caller to explicitly state the name of the second parameter. In that case, you can use '_' because you don't care about the name of that externalized parameter:
func swap(first: Int?, _ second: Int?) {
...
}
This can then be called as swap(5, 6) as opposed to swap(5, second: 6).
2) is there a way to get those values out if you used _. & 3) if so, how?
No. You need to name the variable if you want to use the value.
One example would be a loop where you don't necessarily need the index.
for _ in 0..<10 {
}
In swift you can also externalize the names of the parameters. This allows the caller to pass by name, rather than order:
func myFunction(param1:String, param2:String) {
}
myFunction(param2: "second value", param1: "first value");
If you don't want to externalize the name of a parameter, you can include an underscore before it, like so:
func myFunction(param1:String, _ param2:String) {
}
In this case, you must pass the value to set param2 to as the second argument, and you cannot use the naming scheme seen in the first example.
If you need to use the value inside of a variable, declare it with a name and not _. The underscore says, I know this call returns a value but we're not going to use it, so it doesn't need a name. Swift emits warnings for unused function call results, so this is a way to suppress that warning.
I was wondering: What is the best way to declare a non-ordered list of scalar values in Swift, that are fully backed by a symbol and are liable to be checked by the compiler?
Let's say I want to declare a list of LetterSpacing values that I want to access and use in my code via their symbols.
My understanding is that I should declare an swift enum like this:
enum LetterSpacing: Double {
case Short = 1.0
case Medium = 2.0
case Large = 3.0
}
This works fine and gets compiler checks but the annoying part is that I need to LetterSpacing.XXX.rawValue each time to access the underlying value. The .rawValue bothers me a bit to have to specify this everywhere.
I suppose it wouldn't make sense or would be inappropriate to declare a struct with three static let Short = 1.0 etc..
So, how would you handle such cases? Is it possible to add somekind of protocol/extension swift magic to the existing types to be able to have the Short enum act as its own value? (i.e. let size = LetterSpacing.Short would be of type Double and have a value of 1.0)
The enum would be preferred for multiple reasons.
First, the enum actually ends up with a smaller memory footprint. This is because Swift optimizing enum values into a single byte (no matter what the raw value is), and we only get the full value out of it when we call rawValue on the enum value. Paste the following code into a playground to see:
struct LetterSpacingS {
static let Short: Double = 1.0
}
enum LetterSpacingE: Double {
case Short = 1.0
}
sizeofValue(LetterSpacingS.Short)
sizeofValue(LetterSpacingE.Short)
The double is 8 bytes, while the enum is just 1.
Second, the importance of the first point extends beyond just memory footprint. It can apply to the execution efficiency of our program as well. If we want to compare two values from our struct, we're comparing 8 bytes. If we want to compare two of our enum values, we comparing just a single byte. We have 1/8th as many bytes to compare in this specific case. And this is just with a double. Consider that Swift enums can also have a string as a backing type. Comparing two strings can be extraordinarily expensive versus just comparing the single byte they're hidden behind in an enum.
Third, using the enum, we're not comparing floating point numbers, which you really don't want to do, generally speaking.
Fourth, using the enum gives us some type safety that we can't get with the struct of constants. All the struct of constants does is let us define a handful of predefined constants to use.
struct LetterSpacingS {
static let Short = 1.0
static let Medium = 2.0
static let Long = 3.0
}
But now what would a method look like that expects one of these values?
func setLetterSpacing(spacing: Double) {
// do stuff
}
And now what happens when Joe-Coder comes in and does:
foo.setLetterSpacing(-27.861)
Nothing's stopping him. It takes a double, any double. This might not be so common, but if this is in a library you're distributing, you are leaving yourself open to questions and comments like "When I pass a value of 5.0 in, it doesn't look right at all!"
But compare this to using the enum.
func setLetterSpacing(spacing: LetterSpacing) {
// do stuff
}
And now, we only get the three predefined choices for what to pass into this argument.
And outside of your internal use for the values held by the enum, you should have to use rawValue too much.
The fifth reason isn't a strong reason for using an enum over a struct, but mostly just a point to make to eliminate one of the reasons suggested for using a struct over an enum. Swift enums can be nested in other types, and other types can be nested in Swift enums. You don't have to use a struct to get nested types.
I don't see why creating a Struct with three static constants would be inappropriate. I see a lot of Swift code (also from Apple) that does this.
Structs lets you create nice hierarchies:
struct Style {
struct Colors {
static let backgroundColor = UIColor.blackColor()
...
}
struct LetterSpacing {
static let Short = 1.0
}
...
}
I'm currently practicing examples from Swift Language iBook. My understanding of "let" is that we use "let" to make a constant. Once we assign a value to it, we cannot assign another value to it again. Like the codes below:
let city="NY"
city="LA" <--error (Cannot assign 'let' value city)
But I saw this example on iBook which really confused me:
struct Color{
let red=0.0, green=0.0, blue=0.0 //<---declare variables using "let" and assign value
init(red:Double,green:Double,blue:Double){
self.red=red //<---assign value to variable again?
self.green=green
self.blue=blue
}
}
In this example, it has already assigned values to red, green and blue which use "let".
Why can we assign values to these three variables again in init?
The initialization in the let provides default values if you don't initialize them yourself in the constructor.
Constructors (init) are special. Inside them, you can assign to a constant instance variable. In fact, if you don't have a default value for them, you have to assign to them. (This applies to classes too.)
Thanks to Qwerty Bob for finding this in the docs
Modifying Constant Properties During Initialization
You can modify the value of a constant property at any point during initialization, as long as it is set to a definite value by the time initialization finishes.
Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/us/jEUH0.l
You may set constant variables during the init process, before the self keyword is used. After this they are then truly 'constant'.
You must do it before the self keyword is used, as if you pass it to another object it could in turn call a method of yours which relies on that constant property
And also: structs get passed by value and not by reference, so you cannot modify the variables in a struct at all after their set. So the let keyword really makes sense.
If you continue reading a few paragraphs after the example you gave from the book (unless they use it in multiple locations), it actually talks about this behavior:
You can modify the value of a constant property at any point during
initialization, as long as it is set to a definite value by the time
initialization finishes.
So basically you can modify constants and upon ending the initialization all constants must have a definitive value. It also goes on to talk about how this works with subclasses too:
For class instances, a constant property can only be modified during
initialization by the class that introduces it. It cannot be modified
by a subclass.
Here is the doc reference for it (same as the book), the quoted sections is under the "Modifying Constant Properties During Initialization" subheading.
Apart from the initialization part, which was answered by Kevin, you're still missing the constant part of let. So to clarify let is not exactly a constant.
According to „The Swift Programming Language.” Apple Inc., 2014-05-27T07:00:00Z. iBooks:
Like C, Swift uses variables to store and refer to values by an
identifying name. Swift also makes extensive use of variables whose
values cannot be changed. These are known as constants, and are much
more powerful than constants in C.
Both var and let are references, therefore let is a const reference.
Using fundamental types doesn't really show how let is different than const.
The difference comes when using it with class instances (reference types):
class CTest
{
var str : String = ""
}
let letTest = CTest()
letTest.str = "test" // OK
letTest.str = "another test" // Still OK
//letTest = CTest() // Error
var varTest1 = CTest()
var varTest2 = CTest()
var varTest3 = CTest()
varTest1.str = "var 1"
varTest2.str = "var 2"
varTest3 = varTest1
varTest1.str = "var 3"
varTest3.str // "var 3"