面试题答案
一键面试主要代码结构和关键实现思路
- 定义通用操作协议:首先定义一个协议,该协议包含所有数据存储都需要支持的通用操作,例如读、写操作。
protocol DataStorageProtocol {
associatedtype Value
func write(_ value: Value, forKey key: String)
func read(forKey key: String) -> Value?
}
- 具体存储类型实现:为每种具体的存储类型(如内存存储、文件存储)实现上述协议。
- 内存存储:
class InMemoryStorage<Value>: DataStorageProtocol {
private var storage: [String: Value] = [:]
func write(_ value: Value, forKey key: String) {
storage[key] = value
}
func read(forKey key: String) -> Value? {
return storage[key]
}
}
- **文件存储**:
class FileStorage<Value>: DataStorageProtocol {
private let filePath: String
init(filePath: String) {
self.filePath = filePath
}
func write(_ value: Value, forKey key: String) {
// 实现将value写入文件的逻辑,这里简单示例忽略实际写入细节
let data = try? JSONEncoder().encode(value)
try? data?.write(to: URL(fileURLWithPath: filePath))
}
func read(forKey key: String) -> Value? {
// 实现从文件读取value的逻辑,这里简单示例忽略实际读取细节
guard let data = try? Data(contentsOf: URL(fileURLWithPath: filePath)) else { return nil }
return try? JSONDecoder().decode(Value.self, from: data)
}
}
- 类型擦除:为了避免泛型类型膨胀,使用类型擦除技术。创建一个
AnyDataStorage
结构体,它包装了遵循DataStorageProtocol
的具体类型,并通过eraseToAnyDataStorage
方法来进行类型擦除。
struct AnyDataStorage {
private let base: AnyDataStorageBase
init<Value: Any>(_ storage: some DataStorageProtocol where storage.Value == Value) {
base = AnyDataStorageBaseImpl(storage)
}
func write(_ value: Any, forKey key: String) {
base.write(value, forKey: key)
}
func read(forKey key: String) -> Any? {
return base.read(forKey: key)
}
}
private protocol AnyDataStorageBase {
func write(_ value: Any, forKey key: String)
func read(forKey key: String) -> Any?
}
private class AnyDataStorageBaseImpl<Value: Any, Storage: DataStorageProtocol>: AnyDataStorageBase where Storage.Value == Value {
private let storage: Storage
init(_ storage: Storage) {
self.storage = storage
}
func write(_ value: Any, forKey key: String) {
guard let value = value as? Value else { return }
storage.write(value, forKey: key)
}
func read(forKey key: String) -> Any? {
return storage.read(forKey: key)
}
}
extension DataStorageProtocol {
func eraseToAnyDataStorage() -> AnyDataStorage {
return AnyDataStorage(self)
}
}
- 使用示例:
let inMemory = InMemoryStorage<Int>()
let inMemoryAny = inMemory.eraseToAnyDataStorage()
inMemoryAny.write(10, forKey: "test")
if let result = inMemoryAny.read(forKey: "test") as? Int {
print(result)
}
let file = FileStorage<Double>(filePath: "test.txt")
let fileAny = file.eraseToAnyDataStorage()
fileAny.write(10.5, forKey: "test")
if let result = fileAny.read(forKey: "test") as? Double {
print(result)
}
通过上述步骤,实现了一个灵活的架构,不同存储类型共享通用操作接口,同时利用类型擦除解决了泛型类型膨胀问题。