EXC_BADINSTRUCTION when computing a hash value - swift

The following code will crash with an EXC_BADINSTRUCTION. Im trying to figure out what is the actual cause of the crash, or if there is a better way of computing a hashValue for a given struct.
struct Provider{
let name = "AmazonPrime"
let country = "us"
let identifier = "us-AmazonPrime"
}
let provider = Provider()
//Crash on hashValue
let hashValue = (provider.name.hashValue + provider.country.hashValue + provider.identifier.hashValue)

The Swift language does not allow for math to overflow when using the basic arithmetic operators (as noted in the Arithmetic Operators area of the Basic Operators section of The Swift Programming Guide). If the 3 hash values you're adding exceed Int.max (Hashable declares the hashValue as an Int), you will receive that crash type.
If you want overflow, you have to use the overflow arithmetic operators, as defined in the Overflow Operators area of the Basic Operators section of the Swift Programming Guide.
They are: &+ &- and &*

Related

Usage of Range operator in Data.subdata

In Swift 3, I wonder why I'm able to use the half-open range operator ..< in Data.subdata(in:) but not the closed range operator ....
I've searched everywhere but can't understand why it gives me this error :
no '...' candidates produce the expected contextual result type
'Range' (aka 'Range')
Here's an example of both the one that works and the one doesn't :
import Foundation
let x = Data(bytes: [0x0, 0x1])
let y : UInt8 = x.subdata(in: 0..<2).withUnsafeBytes{$0.pointee}
let z : UInt8 = x.subdata(in: 0...1).withUnsafeBytes{$0.pointee} // This fails
Thanks!
..< is the half-open range operator, which can either create a Range or CountableRange (depending on whether the Bound is Strideable with an Integer Stride or not). The range that is created is inclusive of the lower bound, but exclusive of the upper bound.
... is the closed range operator, which can either create a ClosedRange or CountableClosedRange (same requirements as above). The range that is created is inclusive of both the upper and lower bounds.
Therefore as subdata(in:) expects a Range<Int>, you cannot use the closed range operator ... in order to construct the argument – you must use the half-open range operator instead.
However, it would be trivial to extend Data and add an overload that does accept a ClosedRange<Int>, which would allow you to use the closed range operator.
extension Data {
func subdata(in range: ClosedRange<Index>) -> Data {
return subdata(in: range.lowerBound ..< range.upperBound + 1)
}
}
let x = Data(bytes: [0x0, 0x1])
let z : UInt8 = x.subdata(in: 0...1).withUnsafeBytes {$0.pointee}
At-risk of my comment being closed I'll speak out anyway - I followed the advice of a closed/deleted comment as the selected answer did not work with Swift 5. The working solution was:
x.subdata(in: Range(0...1))
I assume this has to do with interpretations of "Range" vs "NSRange" - but honestly I don't know.

How to compare Range<String.Index> and DefaultBidirectionalIndices<String.CharacterView>?

This comparison worked in Swift 2 but doesn't anymore in Swift 3:
let myStringContainsOnlyOneCharacter = mySting.rangeOfComposedCharacterSequence(at: myString.startIndex) == mySting.characters.indices
How do I compare Range and DefaultBidirectionalIndices?
From SE-0065 – A New Model for Collections and Indices
In Swift 2, collection.indices returned a Range<Index>, but because a range is a simple pair of indices and indices can no longer be advanced on their own, Range<Index> is no longer iterable.
In order to keep code like the above working, Collection has acquired an associated Indices type that is always iterable, ...
Since rangeOfComposedCharacterSequence returns a range of
character indices, the solution is not to use indices, but
startIndex..<endIndex:
myString.rangeOfComposedCharacterSequence(at: myString.startIndex)
== myString.startIndex..<myString.endIndex
As far as I know, String nor String.CharacterView does not have a concise method returning Range<String.Index> or something comparable to it.
You may need to create a Range explicitly with range operator:
let myStringContainsOnlyOneCharacter = myString.rangeOfComposedCharacterSequence(at: myString.startIndex)
== myString.startIndex..<myString.endIndex
Or compare only upper bound, in your case:
let onlyOne = myString.rangeOfComposedCharacterSequence(at: myString.startIndex).upperBound
== myString.endIndex

Swift: How to disable integer overflow / underflow traps for a function

I'm importing some old C code into a swift project, and porting it across to pure swift code.
Some of it does "encryption" wherein it does something like
let a = UInt8(x) // e.g. 30
let b = a - 237
In C this just underflows and wraps around, which is fine for this particular function.
In swift this triggers a fatalError and terminates my program with EXC_BAD_INSTRUCTION because swift by default is designed to catch integer over/underflow.
I'm aware I can turn this checking off at the entire project level by compiling with -Ofast, but I'd really like to just turn off the overflow checking for this one line of code (or perhaps just the specific function itself).
Note: I specifically want to preserve the behaviour of the C function, not just promote things up to Int32 or Int64
This particular term seems really hard to google for.
Update: The answer is the Overflow operators, which are
&- for subtraction
&+ for addition
&* for multiply
I couldn't find them in my previous searching. Oops
You can use addWithOverflow or subtractWithOverflow class method of Int, UInt8 etc types
E.g. let b = UInt8.subtractWithOverflow(a, 237)
Apart from overflow operators (such as &+ , &* etc) you can make use of reporting overflow methods (available for integers) to know whether the arithmetic operation resulted in an overflow or not such as this example :
let int1 : Int8 = Int8.max //127
let int2: Int8 = 50
//this method provides a boolean flag
let (sum1,didOverflow ):(Int8,Bool) = int1.addingReportingOverflow(int2)
print("sum is \(sum1) and isOverflowing = \(didOverflow)")
//sum is -79 and isOverflowing is true
let sum = int1 &+ int2 //wont crash for overflows
let unsafeSum = int1.unsafeAdding(int2) //crashes whenever overflow

How to sort structures by property in Swift [duplicate]

This question already has answers here:
How to sort an array of custom objects by property value in Swift
(20 answers)
Closed 7 years ago.
I am trying to sort an array of structure depending on its property.
Lets say I want to sort an array of NSViews by the x coordinate.
How can I achive this?
Its a very pretty solution for that, and its called Closure Expression Syntax.
What you need to do is:
let sortedArray = sorted(allViewsArray, { (p1: NSView, p2: NSView) -> Bool in
return p1.frame.origin.x < p2.frame.origin.x
})
This will sort the alLViewsArray from the biggest X coordinate to the smallest, and store it in sortedArary.
Note, you can simplify the syntax a little, which often helps with readability (focus is on what you’re doing rather than the syntax of the types etc):
let sortedArray = sorted(allViewsArray) {
$0.frame.origin.x < $1.frame.origin.x
}
Trailing closures can be outside the function call parens, resembling other block structures like if or while; you can skip the return if the closure expression is a single statement, and you can skip the function signature and use $0, $1 etc. for the argument names.
That last one is best used only when there are no more useful names to be had (e.g. p1 is no more descriptive than $0). If you do want to give them names, you can still skip the types:
let sortedArray = sorted(allViewsArray) { p1, p2 in
p1.frame.origin.x < p2.frame.origin.x
}
Swift is sometimes a little fragile when applying this syntax sugar so occasionally you’ll find it can’t be shortened quite as much as it ought, but it usually works.

How exactly does the "let" keyword work in Swift?

I've read this simple explanation in the guide:
The value of a constant doesn’t need to be known at compile time, but you must assign it a value exactly once.
But I want a little more detail than this. If the constant references an object, can I still modify its properties? If it references a collection, can I add or remove elements from it? I come from a C# background; is it similar to how readonly works (apart from being able to use it in method bodies), and if it's not, how is it different?
let is a little bit like a const pointer in C. If you reference an object with a let, you can change the object's properties or call methods on it, but you cannot assign a different object to that identifier.
let also has implications for collections and non-object types. If you reference a struct with a let, you cannot change its properties or call any of its mutating func methods.
Using let/var with collections works much like mutable/immutable Foundation collections: If you assign an array to a let, you can't change its contents. If you reference a dictionary with let, you can't add/remove key/value pairs or assign a new value for a key — it's truly immutable. If you want to assign to subscripts in, append to, or otherwise mutate an array or dictionary, you must declare it with var.
(Prior to Xcode 6 beta 3, Swift arrays had a weird mix of value and reference semantics, and were partially mutable when assigned to a let -- that's gone now.)
It's best to think of let in terms of Static Single Assignment (SSA) -- every SSA variable is assigned to exactly once. In functional languages like lisp you don't (normally) use an assignment operator -- names are bound to a value exactly once. For example, the names y and z below are bound to a value exactly once (per invocation):
func pow(x: Float, n : Int) -> Float {
if n == 0 {return 1}
if n == 1 {return x}
let y = pow(x, n/2)
let z = y*y
if n & 1 == 0 {
return z
}
return z*x
}
This lends itself to more correct code since it enforces invariance and is side-effect free.
Here is how an imperative-style programmer might compute the first 6 powers of 5:
var powersOfFive = Int[]()
for n in [1, 2, 3, 4, 5, 6] {
var n2 = n*n
powersOfFive += n2*n2*n
}
Obviously n2 is is a loop invariant so we could use let instead:
var powersOfFive = Int[]()
for n in [1, 2, 3, 4, 5, 6] {
let n2 = n*n
powersOfFive += n2*n2*n
}
But a truly functional programmer would avoid all the side-effects and mutations:
let powersOfFive = [1, 2, 3, 4, 5, 6].map(
{(num: Int) -> Int in
let num2 = num*num
return num2*num2*num})
Let
Swift uses two basic techniques to store values for a programmer to access by using a name: let and var. Use let if you're never going to change the value associated with that name. Use var if you expect for that name to refer to a changing set of values.
let a = 5 // This is now a constant. "a" can never be changed.
var b = 2 // This is now a variable. Change "b" when you like.
The value that a constant refers to can never be changed, however the thing that a constant refers to can change if it is an instance of a class.
let a = 5
let b = someClass()
a = 6 // Nope.
b = someOtherClass() // Nope.
b.setCookies( newNumberOfCookies: 5 ) // Ok, sure.
Let and Collections
When you assign an array to a constant, elements can no longer be added or removed from that array. However, the value of any of that array's elements may still be changed.
let a = [1, 2, 3]
a.append(4) // This is NOT OK. You may not add a new value.
a[0] = 0 // This is OK. You can change an existing value.
A dictionary assigned to a constant can not be changed in any way.
let a = [1: "Awesome", 2: "Not Awesome"]
a[3] = "Bogus" // This is NOT OK. You may not add new key:value pairs.
a[1] = "Totally Awesome" // This is NOT OK. You may not change a value.
That is my understanding of this topic. Please correct me where needed. Excuse me if the question is already answered, I am doing this in part to help myself learn.
First of all, "The let keyword defines a constant" is confusing for beginners who are coming from C# background (like me). After reading many Stack Overflow answers, I came to the conclusion that
Actually, in swift there is no concept of constant
A constant is an expression that is resolved at compilation time. For both C# and Java, constants must be assigned during declaration:
public const double pi = 3.1416; // C#
public static final double pi = 3.1416 // Java
Apple doc ( defining constant using "let" ):
The value of a constant doesn’t need to be known at compile time, but you must assign the value exactly once.
In C# terms, you can think of "let" as "readonly" variable
Swift "let" == C# "readonly"
F# users will feel right at home with Swift's let keyword. :)
In C# terms, you can think of "let" as "readonly var", if that construct was allowed, i.e.: an identifier that can only be bound at the point of declaration.
Swift properties:
Swift Properties official documentation
In its simplest form, a stored property is a constant or variable that is stored as part of an instance of a particular class or structure. Stored properties can be either variable stored properties (introduced by the varkeyword) or constant stored properties (introduced by the let keyword).
Example:
The example below defines a structure called FixedLengthRange, which describes a range of integers whose range length cannot be changed once it is created:
struct FixedLengthRange {
var firstValue: Int
let length: Int
}
Instances of FixedLengthRange have a variable stored property called firstValue and a constant stored property called length. In the example above, length is initialized when the new range is created and cannot be changed thereafter, because it is a constant property.