Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
能否在Swift中同时定义和实例化隐式类型?_Swift_Swift4_Settings_Nsuserdefaults_Implicit Typing - Fatal编程技术网

能否在Swift中同时定义和实例化隐式类型?

能否在Swift中同时定义和实例化隐式类型?,swift,swift4,settings,nsuserdefaults,implicit-typing,Swift,Swift4,Settings,Nsuserdefaults,Implicit Typing,我只是在考虑如何构建一些基于层次结构自动生成键的UserDefaults。这让我想知道。。。可以像这样同时定义和实例化一个类型吗 let myUserSettings = { let formatting = { var lastUsedFormat:String } } let lastUsedFormat = myUserSettings.formatting.lastUsedFormat 注意:我不能使用静态,因为我特别需要实例化,所以带有静态成员

我只是在考虑如何构建一些基于层次结构自动生成键的UserDefaults。这让我想知道。。。可以像这样同时定义和实例化一个类型吗

let myUserSettings = {

    let formatting = {

        var lastUsedFormat:String

    }
}

let lastUsedFormat = myUserSettings.formatting.lastUsedFormat
注意:我不能使用静态,因为我特别需要实例化,所以带有静态成员的嵌套结构/类将不适用于我的情况

这是我能想到的最接近的东西,但我讨厌我必须创建初始值设定项来设置成员。我希望能少点罗嗦

class DefaultsScope {

    init(_ userDefaults:UserDefaults){
        self.userDefaults = userDefaults
    }

    let userDefaults:UserDefaults

    func keyForSelf(property:String = #function) -> String {
        return "\(String(reflecting: self)).\(property)"
    }
}

let sharedDefaults = SharedDefaults(UserDefaults(suiteName: "A")!)
class SharedDefaults : DefaultsScope {

    override init(_ userDefaults:UserDefaults){
        formatting = Formatting(userDefaults)
        misc       = Misc(userDefaults)
        super.init(userDefaults)
    }

    let formatting:Formatting
    class Formatting:DefaultsScope {

        let maxLastUsedFormats = 5

        fileprivate(set) var lastUsedFormats:[String]{
            get { return userDefaults.stringArray(forKey:keyForSelf()) ?? [] }
            set { userDefaults.set(newValue, forKey:keyForSelf()) }
        }

        func appendFormat(_ format:String) -> [String] {

            var updatedListOfFormats = Array<String>(lastUsedFormats.suffix(maxLastUsedFormats - 1))
            updatedListOfFormats.append(format)
            lastUsedFormats = updatedListOfFormats

            return updatedListOfFormats
        }
    }

    let misc:Misc
    class Misc:DefaultsScope {

        var someBool:Bool{
            get { return userDefaults.bool(forKey:keyForSelf()) }
            set { userDefaults.set(newValue, forKey:keyForSelf()) }
        }
    }
}
class DefaultsScope{
init(uUserDefaults:userDefaults){
self.userDefaults=userDefaults
}
let userDefaults:userDefaults
func keyForSelf(属性:String=#function)->String{
返回“\(字符串(反射:self))。\(属性)”
}
}
让sharedDefaults=sharedDefaults(用户默认值(suiteName:“A”)!)
类SharedDefaults:DefaultsScope{
重写init(userDefaults:userDefaults){
格式化=格式化(用户默认值)
杂项=杂项(用户默认值)
super.init(userDefaults)
}
let格式化:格式化
类格式:DefaultsScope{
设maxLastUsedFormats=5
fileprivate(set)var lastUsedFormats:[字符串]{
获取{return userDefaults.stringArray(forKey:keyForSelf())??[]
set{userDefaults.set(newValue,forKey:keyForSelf())}
}
func appendFormat(uFormat:String)->[String]{
var updatedListOfFormats=数组(lastUsedFormats.suffix(maxLastUsedFormats-1))
updatedListOfFormats.append(格式)
lastUsedFormats=updatedListOfFormats
返回updatedListOfFormats
}
}
让杂项:杂项
类别杂项:DefaultsScope{
var someBool:Bool{
获取{return userDefaults.bool(forKey:keyForSelf())}
set{userDefaults.set(newValue,forKey:keyForSelf())}
}
}
}

那么有没有更简单的方法呢?

免责声明:这可能只是一个抽象的解决方案,不应该在现实生活中使用:)

更新:对不起,各位,我不能停止试验。这个看起来很糟糕:)

更新2:再试一次,这次是元组。由于元组必须至少有两个值,所以我必须在其中添加一些假人。此外,元组不能有变异函数

let x3 = (
  y3: (
    success: {
      print("Success")
    },
    failure: {
      print("Failure")
    }
  ),
  z3: 0
)
x3.y3.success()

你不能有这样的结构,但你不能从x的内部访问y,因为y只在x的范围内可见,y的范围内成功也是如此。您无法从外部访问它们

另一种选择是使用这样的高阶函数,它返回可调用的闭包

let x = {
            {
                {
                    print("Success")
                }
            }
        }

let y = x()
let success = y()
success()

用户默认值的高阶函数的实际用法可能是这样的

typealias StringType = (String) -> ((String) -> Void)
typealias IntType = (String) -> ((Int) -> Void)
typealias BoolType = (String) -> ((Bool) -> Void)

typealias StringValue = (String) -> String?
typealias IntValue = (String) -> Int?
typealias BoolValue = (String) -> Bool?

func userDefaults<T>(_ defaults: UserDefaults) -> (String) -> ((T) ->  Void) {
    return { key in
        return { value in
            defaults.setValue(value, forKey: key)
        }
    }
}

func getDefaultsValue<T>(_ defaults: UserDefaults) -> (String) -> T? {
    return { key in
        return defaults.value(forKey: key) as? T
    }
}

let setStringDefaults: StringType  = userDefaults(.standard)
setStringDefaults("Name")("Jack Jones")
setStringDefaults("Address")("Australia")

let setIntDefaults: IntType = userDefaults(.standard)
setIntDefaults("Age")(35)
setIntDefaults("Salary")(2000)

let setBoolDefaults: BoolType = userDefaults(.standard)
setBoolDefaults("Married")(false)
setBoolDefaults("Employed")(true)

let getStringValue: StringValue = getDefaultsValue(.standard)
let name = getStringValue("Name")
let address = getStringValue("Address")

let getIntValue: IntValue = getDefaultsValue(.standard)
let age = getIntValue("Age")
let salary = getIntValue("Salary")

let getBoolValue: BoolValue = getDefaultsValue(.standard)
let married = getBoolValue("Married")
let employed = getBoolValue("Employed")
typealias StringType=(字符串)->(字符串)->Void)
typealias IntType=(字符串)->((Int)->Void)
typealias BoolType=(字符串)->(Bool)->Void)
typealias StringValue=(字符串)->字符串?
typealias IntValue=(字符串)->Int?
typealias布尔值=(字符串)->Bool?
func userDefaults(defaults:userDefaults)->(String)->(T)->Void){
返回{输入
返回{中的值
defaults.setValue(值,forKey:key)
}
}
}
func getDefaultsValue(u默认值:UserDefaults)->(字符串)->T?{
返回{输入
将defaults.value(forKey:key)返回为?T
}
}
让setStringDefaults:StringType=userDefaults(.standard)
setStringDefaults(“名称”)(“杰克·琼斯”)
setStringDefaults(“地址”)(“澳大利亚”)
让setIntDefaults:IntType=userDefaults(.standard)
设置默认值(“年龄”)(35)
设定默认值(“工资”)(2000年)
让setBoolDefaults:BoolType=userDefaults(.standard)
“已婚”(假)
设置默认值(“已使用”)(真)
让getStringValue:StringValue=getDefaultsValue(.standard)
让name=getStringValue(“name”)
let address=getStringValue(“地址”)
让getIntValue:IntValue=getDefaultsValue(.standard)
让年龄=getIntValue(“年龄”)
让工资=getIntValue(“工资”)
让getBoolValue:BoolValue=getDefaultsValue(.standard)
让已婚=获得布尔值(“已婚”)
let employed=getBoolValue(“employed”)
我不确定您是否喜欢该模式,但正如您从下面可以看到的,它有一些很好的用例,setStringDefaults您可以将stringValue设置为string key,并且所有这些都是类型安全的


您可以为您的用例扩展它。但是,您也可以使用struct和命令式代码,这可能更容易理解。我也从中看到了美。

你试试嵌套一些swift
结构怎么样

struct x {
    struct y {
        static func success() {
            print("success")
        }
    }
}

x.y.success()    

好的,我想我已经明白了。第一个类可以放在你所有应用程序使用的公共库中

class SettingsScopeBase {

    private init(){}

    static func getKey(setting:String = #function) -> String {
        return "\(String(reflecting:self)).\(setting)"
    }
}
下一部分是一对类:

  • 定义要使用的用户默认实例的“作用域”类(以及您可能要为此特定设置实例指定的任何其他内容)
  • 定义设置的实际层次结构
  • 这是第一个。我正在为我的应用程序及其扩展之间的共享设置设置:

    class SharedSettingsScope : SettingsScopeBase{
        static let defaults = UserDefaults(suiteName: "group.com.myco.myappgroup")!
    }
    
    最后,这里介绍了如何“设置”层次结构以及如何实现属性的主体

    class SharedSettings:SharedSettingsScope{
    
        class Formatting:SharedSettingsScope{
    
            static var groupsOnWhitespaceOnlyLines:Bool{
                get { return defaults.bool(forKey: getKey()) }
                set { defaults.set(newValue, forKey: getKey()) }
            }
        }
    }
    
    下面是你如何使用它们

    let x = SharedSettings.Formatting.groupsOnWhitespaceOnlyLines
    // x = false
    
    SharedSettings.Formatting.groupsOnWhitespaceOnlyLines = true
    
    let y = SharedSettings.Formatting.groupsOnWhitespaceOnlyLines
    // y = true
    

    我会看看我是否可以再细化/优化它一点,但这已经非常接近我想要的了。没有硬编码字符串,键由使用它们的层次结构定义,并且只在一个位置设置特定的UserDefaults实例。

    这是我最初拥有的,尽管我在嵌套结构上使用静态。问题是您没有对象的实例。你在给它打电话。再说一次,如果没有具体的类型信息,我甚至不确定它是否重要!为什么你要使用枚举而不是类或结构?@4kman这只是一个尝试,可以
    class SharedSettingsScope : SettingsScopeBase{
        static let defaults = UserDefaults(suiteName: "group.com.myco.myappgroup")!
    }
    
    class SharedSettings:SharedSettingsScope{
    
        class Formatting:SharedSettingsScope{
    
            static var groupsOnWhitespaceOnlyLines:Bool{
                get { return defaults.bool(forKey: getKey()) }
                set { defaults.set(newValue, forKey: getKey()) }
            }
        }
    }
    
    let x = SharedSettings.Formatting.groupsOnWhitespaceOnlyLines
    // x = false
    
    SharedSettings.Formatting.groupsOnWhitespaceOnlyLines = true
    
    let y = SharedSettings.Formatting.groupsOnWhitespaceOnlyLines
    // y = true