F# - 函数不返回更新的数据
F# - Function not returning updated data
我有一个函数 GetCars,它没有 return 更新状态。如果我添加一个参数,它可以正常工作,或者如果我在其他函数中执行相同的代码,它也可以正常工作。
open System
open System.Collections.Concurrent
type Car = {
Make : string
Model : string
ID : int
}
type Cars = {
Count : int
Collection : Car[]
}
module AppState = begin
let state = new ConcurrentDictionary<string, obj>()
let added = state.TryAdd("cars", {
Count = 1
Collection = [| { Make = "Honda"; Model = "Civic"; ID = 0 } |]
})
let DownCastCars (o : obj) =
match o with
| :? Cars as cars -> Some(cars)
| _ -> None
let GetCars =
let mutable cars : obj = null;
let success = state.TryGetValue("cars", &cars)
if success then
DownCastCars cars
else
None
let AddCar car =
match GetCars with
| Some cars ->
state.TryUpdate("cars", { cars with Collection = Array.append cars.Collection [| car |] }, cars)
| None ->
false
end
let AddCarMakeModel make model =
let car : Car = {
Make = make
Model = model
ID = match AppState.GetCars with
| Some cars -> cars.Collection.Length
| None -> 0
}
let success = AppState.AddCar car
if success then
printfn "Successfully added car :)"
else
printfn "Failed to add car :("
[<EntryPoint>]
let main argv =
AddCarMakeModel "Honda" "Civic"
AddCarMakeModel "Honda" "Civic LX"
printfn "Press any key to continue"
let s = Console.ReadLine()
0 // return an integer exit code
如果我向 GetCars 添加一个参数,即
let GetCars notused =
let mutable cars : obj = null;
let success = state.TryGetValue("cars", &cars)
if success then
DownCastCars cars
else
None
然后 GetCars 函数每次都会 return 最新的值。或者,如果我只是将相同的代码放在我正在使用的其他方法中,即
let AddCarMakeModel Make Model =
let car : Car = {
Make = make
Model = model
ID = match AppState.GetCars with
| Some cars -> cars.Collection.Length
| None -> 0
}
let success = AppState.AddCar car
if success then
printfn "Successfully added car :)"
else
printfn "Failed to add car :("
我猜这与 "Do Bindings" 有关,但我不确定如何将其成功应用于 GetCars。我注意到 GetCars 在应用程序启动时被调用,如果我在函数内设置断点,它就再也不会那么远了。
如评论中所述,解决方案是添加一个单位参数。
问题是您声明的是常量值,而不是函数值。
看签名就知道了:val GetCars : Cars option
没有箭头,只有一个值,所以GetCars
只会执行一次,绑定到右边的值表达式。
通过添加一个单元参数,您可以获得签名:val GetCars : unit -> Cars option
所以现在在调用站点,您可以单独通过 GetCars
引用函数值,或者执行它并通过GetCars()
.
另请注意,您不需要可变变量,因为 F# 将返回值和引用的函数视为元组,您可以这样写 GetCars
:
let GetCars() =
match state.TryGetValue("cars") with
| true, (:? Cars as cars) -> Some cars
| _ -> None
然后去掉函数DownCastCars
。
我有一个函数 GetCars,它没有 return 更新状态。如果我添加一个参数,它可以正常工作,或者如果我在其他函数中执行相同的代码,它也可以正常工作。
open System
open System.Collections.Concurrent
type Car = {
Make : string
Model : string
ID : int
}
type Cars = {
Count : int
Collection : Car[]
}
module AppState = begin
let state = new ConcurrentDictionary<string, obj>()
let added = state.TryAdd("cars", {
Count = 1
Collection = [| { Make = "Honda"; Model = "Civic"; ID = 0 } |]
})
let DownCastCars (o : obj) =
match o with
| :? Cars as cars -> Some(cars)
| _ -> None
let GetCars =
let mutable cars : obj = null;
let success = state.TryGetValue("cars", &cars)
if success then
DownCastCars cars
else
None
let AddCar car =
match GetCars with
| Some cars ->
state.TryUpdate("cars", { cars with Collection = Array.append cars.Collection [| car |] }, cars)
| None ->
false
end
let AddCarMakeModel make model =
let car : Car = {
Make = make
Model = model
ID = match AppState.GetCars with
| Some cars -> cars.Collection.Length
| None -> 0
}
let success = AppState.AddCar car
if success then
printfn "Successfully added car :)"
else
printfn "Failed to add car :("
[<EntryPoint>]
let main argv =
AddCarMakeModel "Honda" "Civic"
AddCarMakeModel "Honda" "Civic LX"
printfn "Press any key to continue"
let s = Console.ReadLine()
0 // return an integer exit code
如果我向 GetCars 添加一个参数,即
let GetCars notused =
let mutable cars : obj = null;
let success = state.TryGetValue("cars", &cars)
if success then
DownCastCars cars
else
None
然后 GetCars 函数每次都会 return 最新的值。或者,如果我只是将相同的代码放在我正在使用的其他方法中,即
let AddCarMakeModel Make Model =
let car : Car = {
Make = make
Model = model
ID = match AppState.GetCars with
| Some cars -> cars.Collection.Length
| None -> 0
}
let success = AppState.AddCar car
if success then
printfn "Successfully added car :)"
else
printfn "Failed to add car :("
我猜这与 "Do Bindings" 有关,但我不确定如何将其成功应用于 GetCars。我注意到 GetCars 在应用程序启动时被调用,如果我在函数内设置断点,它就再也不会那么远了。
如评论中所述,解决方案是添加一个单位参数。
问题是您声明的是常量值,而不是函数值。
看签名就知道了:val GetCars : Cars option
没有箭头,只有一个值,所以GetCars
只会执行一次,绑定到右边的值表达式。
通过添加一个单元参数,您可以获得签名:val GetCars : unit -> Cars option
所以现在在调用站点,您可以单独通过 GetCars
引用函数值,或者执行它并通过GetCars()
.
另请注意,您不需要可变变量,因为 F# 将返回值和引用的函数视为元组,您可以这样写 GetCars
:
let GetCars() =
match state.TryGetValue("cars") with
| true, (:? Cars as cars) -> Some cars
| _ -> None
然后去掉函数DownCastCars
。