Есть переменная с несколькими типами в Swift - PullRequest
0 голосов
/ 26 октября 2018

Я хотел бы иметь переменную, которая может иметь несколько типов (только те, которые я определил), например:

var example: String, Int = 0
example = "hi"

Эта переменная должна иметь возможность хранить только значения типа Int и String.

Возможно ли это?

Спасибо за помощь;)

Ответы [ 4 ]

0 голосов
/ 26 октября 2018

Вот как вы можете этого достичь. Работает именно так, как вы ожидаете.

protocol StringOrInt { }

extension Int: StringOrInt { }
extension String: StringOrInt { }

var a: StringOrInt = "10"
a = 10 //> 10
a = "q" //> "q"
a = 0.8 //> Error

NB! Я бы не советовал вам использовать его в рабочем коде. Это может сбить с толку ваших товарищей по команде.

UPD: как упомянуто @Martin R: Обратите внимание, что это ограничивает возможные типы только «по соглашению». Любой модуль (или исходный файл) может добавить extension MyType: StringOrInt { } соответствие.

0 голосов
/ 26 октября 2018

«Перечисление со связанным значением» может быть тем, что вы ищете:

enum StringOrInt {
    case string(String)
    case int(Int)
}

Вы можете назначить строку или целое число:

var value: StringOrInt
value = .string("Hello")
// ...
value = .int(123)

Получение содержимого осуществляется с помощью оператора switch:

switch value {
case .string(let s): print("String:", s)
case .int(let n): print("Int:", n)
}

Если вы заявляете о соответствии протоколу Equatable, то Вы также можете проверить значения на равенство:

enum StringOrInt: Equatable {
    case string(String)
    case int(Int)
}

let v = StringOrInt.string("Hi")
let w = StringOrInt.int(0)
if v == w { ... }
0 голосов
/ 26 октября 2018

Вы можете использовать Tuple.

Пример:

let example: (String, Int) = ("hi", 0)

И получить доступ к каждой информации по индексу:

let stringFromExampleTuple = example.0 // "hi"
let intFromtExampleTuple = example.1 // 0
0 голосов
/ 26 октября 2018

Нет, это невозможно для классов, структур и т. Д.

Но это возможно для протоколов.

Вы можете это:

protocol Walker {
func go()
}
protocol Sleeper {
func sleep()
}

var ab = Walker & Sleeper

или даже

    struct Person {
    var name: String
    }


var ab = Person & Walker & Sleeper

Но я не рекомендую использовать этот способ.

Более полезно это:

struct Person: Walker, Sleeper {
/// code
}
var ab = Person
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...