Оператор равенства перегрузки (==) для сравнения строк и Int - PullRequest
0 голосов
/ 20 сентября 2019

Я сталкиваюсь с протоколами и решил написать фрагмент кода, который перегружает оператор ==, чтобы он returns true при сравнении случайного String со значением "42" со значением Int 42.Пожалуйста, не ставьте под сомнение полезность, просто возвращая 42 на String, главное - заставить Equality Operator работать на двух разных типах.

Вот что я попробовал:

Версия 1

import Foundation

protocol IntTransformable: Equatable {
    func toInt() -> Int
}

extension String: IntTransformable {
    func toInt() -> Int {
        return 42
    }
}

extension Int: IntTransformable {
    func toInt() -> Int {
        return self
    }
}

extension IntTransformable {
    static func == (lhs: Self, rhs: Self) -> Bool {
        return lhs.toInt() == rhs.toInt()
    }
}

// throws: Ambiguous reference to operator function '=='
if "42" == 42 {
    print("equal")
} else {
    print("unequal")
}

Версия 2

import Foundation

protocol IntTransformable: Equatable {
    func toInt() -> Int
}

extension String: IntTransformable {
    func toInt() -> Int {
        return 42
    }
}

extension Int: IntTransformable {
    func toInt() -> Int {
        return self
    }
}

extension IntTransformable {
    // throws: Protocol 'IntTransformable' can only be used as a generic constraint because it has Self or associated type requirements
    static func == (lhs: IntTransformable, rhs: IntTransformable) -> Bool {
        return lhs.toInt() == rhs.toInt()
    }
}

// throws: Ambiguous reference to operator function '=='
if "42" == 42 {
    print("equal")
} else {
    print("unequal")
}

Ответы [ 3 ]

3 голосов
/ 20 сентября 2019

Вы должны использовать эти две функции:

func ==(lhs: String, rhs: @autoclosure ()->Int) -> Bool {
    guard let stringIntValue = Int(lhs) else { return false }
    return stringIntValue == rhs()
}

func ==(lhs: Int, rhs: String) -> Bool {
    guard let stringIntValue = Int(rhs) else { return false }
    return lhs == stringIntValue
}

Но если вы действительно хотите задействовать Protocol s здесь, вы должны сделать это следующим образом:

extension IntTransformable {
    static func ==<T: IntTransformable>(lhs: Self, rhs: T) -> Bool {
        return lhs.toInt() == rhs.toInt()
    }
}

Использование:

print( 42 == "42" )
print( "42" == 42 )
1 голос
/ 20 сентября 2019

Ты слишком много думаешь об этом.Здесь нет причин использовать протоколы, и вы действительно не можете этого сделать, потому что протоколы не являются типами.Просто напишите свой оператор (ы) на верхнем уровне:

func == (lhs: Int, rhs: String) -> Bool {
    return lhs == Int(rhs)
}
func == (lhs: String, rhs: Int) -> Bool {
    return Int(lhs) == rhs
}

Тестирование:

print(5 == "5") // true
0 голосов
/ 20 сентября 2019

создать расширение строки, например

открытая строка ToInt (это значение типа int) {// некоторый код преобразования

return ConvertedStringValue;}

или вы можете использовать uint.TryParse (строковое значение, вывод uint), этот оператор вернет true, если преобразование выполнено успешно.

...