斯威夫特数字泛型? [英] Swift number generics?

查看:78
本文介绍了斯威夫特数字泛型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个功能,可以根据两个数字计算斜边

I have this function that is going to calculate the hypotenuse from 2 numbers

func hypotenusa<T>(nr1: T, nr2: T) -> T {
    return sqrt( pow(nr1, 2) + pow(nr2, 2) )
}

// v Simpler situation v

func addition<T>(nr1: T, nr2: T) -> T {
    return nr1 + nr2
}

我想使用泛型,因此我不必为此分别使用Int,Float,Double制作3个副本

I want to use generics so I don't have to make 3 copies of this which uses Int, Float, Double separately

但是这不起作用,我认为泛型真的很难使用,请帮助我:)

But this isn't working, I think generics is really difficult to work with, please help me :)

推荐答案

Swift泛型与C ++模板不同.

Swift generics aren't like C++ templates.

在C ++中,您可以随意使用所需的参数化类型,并且在编译器尝试使用某种不支持模板尝试执行的类型实例化模板之前,这不是错误.

In C++, you can just try to use a parameterized type however you want, and it's not an error until the compiler tries to instantiate the template with some type that doesn't support what your template tries to do.

在Swift中,泛型构造只能在首次解析泛型构造时以已知有效的方式使用参数化类型.您可以通过使用协议约束参数化类型来指定这些已知有效方式".

In Swift, the generic construct can only use a parameterized type in ways known to be valid when the generic construct is first parsed. You specify these "ways known to be valid" by constraining the parameterized type with protocols.

您不能使用泛型类型的参数调用sqrtpow,因为这些函数本身不是泛型的.它们有两个定义:

You cannot call sqrt or pow with generic-typed arguments, because those functions are not themselves generic. They have each two definitions:

func pow(_: Double, _: Double) -> Double
func pow(lhs: Float, rhs: Float) -> Float
func sqrt(x: Double) -> Double
func sqrt(x: Float) -> Float

您可以编写hypotenusa的特定于类型的版本:

You could write type-specific versions of hypotenusa:

func hypotenusa(a: Float, b: Float) -> Float
func hypotenusa(a: Double, b: Double) -> Double
func hypotenusa(a: CGFloat, b: CGFloat) -> CGFloat

我不确定为什么要创建Int版本,因为很少有直角三角形具有整数斜边.

I'm not sure why you'd create an Int version at all, since very few right triangles have integer hypotenuses.

无论如何,您根本不需要定义FloatDouble版本,因为标准库已经提供了在FloatDouble上定义的hypot函数:

Anyway, you don't need to define the Float and Double versions at all, because the standard library already provides a hypot function defined on Float and Double:

func hypot(_: Double, _: Double) -> Double
func hypot(lhs: Float, rhs: Float) -> Float

您可以为CGFloat创建另一个替代:

You could create another override for CGFloat:

func hypot(l: CGFloat, r: CGFloat) -> CGFloat {
    return hypot(Double(l), Double(r))
}

对于您的addition函数,它与您的hypotenusa函数具有相同的问题:+运算符不是完全通用的定义.它具有一些通用定义(与sqrtpow不同),但仅覆盖整数类型(请参见IntegerArithmeticType).没有+的通用定义涵盖浮点类型. Swift使用显式类型定义了所有这些+版本:

As for your addition function, it has the same problem as your hypotenusa function: the + operator is not defined entirely generically. It has some generic definitions (unlike sqrt and pow), but those only cover the integer types (see IntegerArithmeticType). There's not generic definition of + that covers the floating-point types. Swift defines all of these versions of + with explicit types:

func +(lhs: Float, rhs: Float) -> Float
func +<T>(lhs: Int, rhs: UnsafePointer<T>) -> UnsafePointer<T>
func +<T>(lhs: UnsafePointer<T>, rhs: Int) -> UnsafePointer<T>
func +(lhs: Int, rhs: Int) -> Int
func +(lhs: UInt, rhs: UInt) -> UInt
func +(lhs: Int64, rhs: Int64) -> Int64
func +(lhs: UInt64, rhs: UInt64) -> UInt64
func +<T>(lhs: Int, rhs: UnsafeMutablePointer<T>) -> UnsafeMutablePointer<T>
func +<T>(lhs: UnsafeMutablePointer<T>, rhs: Int) -> UnsafeMutablePointer<T>
func +(lhs: Int32, rhs: Int32) -> Int32
func +(lhs: UInt32, rhs: UInt32) -> UInt32
func +(lhs: Int16, rhs: Int16) -> Int16
func +(lhs: UInt16, rhs: UInt16) -> UInt16
func +(lhs: Int8, rhs: Int8) -> Int8
func +(lhs: UInt8, rhs: UInt8) -> UInt8
func +(lhs: Double, rhs: Double) -> Double
func +(lhs: String, rhs: String) -> String
func +(lhs: Float80, rhs: Float80) -> Float80

这篇关于斯威夫特数字泛型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆