I want to make a function accept any number (Int, Float, Double, ...) in Swift
func myFunction <T : "What to put here"> (number : T) -> { //... }
without using NSNumber
Example: Swift Generic Function In the above example, we have created a generic function named displayData() with the type parameter <T> . we have passed a string value, so the placeholder parameter T is automatically replaced by String . the placeholder is replaced by Int .
Swift enables us to create generic types, protocols, and functions, that aren't tied to any specific concrete type — but can instead be used with any type that meets a given set of requirements.
Protocol is a very powerful feature of the Swift programming language. Protocols are used to define a “blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality.”
Generics allow you to declare a variable which, on execution, may be assigned to a set of types defined by us. In Swift, an array can hold data of any type. If we need an array of integers, strings, or floats, we can create one with the Swift standard library.
Update: The answer below still applies in principle, but Swift 4 completed a redesign of the numeric protocols, such that adding your own is often unnecessary. Take a look at the standard library's numeric protocols before you build your own system.
This actually isn't possible out of the box in Swift. To do this you'll need to create a new protocol, declared with whatever methods and operators you're going to use inside your generic function. This process will work for you, but the exact details will depend a little on what your generic function does. Here's how you'd do it for a function that gets a number n
and returns (n - 1)^2
.
First, define your protocol, with the operators and an initializer that takes an Int
(that's so we can subtract one).
protocol NumericType { func +(lhs: Self, rhs: Self) -> Self func -(lhs: Self, rhs: Self) -> Self func *(lhs: Self, rhs: Self) -> Self func /(lhs: Self, rhs: Self) -> Self func %(lhs: Self, rhs: Self) -> Self init(_ v: Int) }
All of the numeric types already implement these, but at this point the compiler doesn't know that they conform to the new NumericType
protocol. You have to make this explicit -- Apple calls this "declaring protocol adoption with an extension." We'll do this for Double
, Float
, and all the integer types:
extension Double : NumericType { } extension Float : NumericType { } extension Int : NumericType { } extension Int8 : NumericType { } extension Int16 : NumericType { } extension Int32 : NumericType { } extension Int64 : NumericType { } extension UInt : NumericType { } extension UInt8 : NumericType { } extension UInt16 : NumericType { } extension UInt32 : NumericType { } extension UInt64 : NumericType { }
Now we can write our actual function, using the NumericType
protocol as a generic constraint.
func minusOneSquared<T : NumericType> (number : T) -> T { let minusOne = number - T(1) return minusOne * minusOne } minusOneSquared(5) // 16 minusOneSquared(2.3) // 1.69 minusOneSquared(2 as UInt64) // 1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With