是否可以在 F# 的管道中使用实例方法?
Is it possible to use an instance method in a pipeline in F#?
是否可以在 F# 的管道中直接使用实例方法?我问的是一般情况,但这里有一个例子。
假设我试图在管道内将字符串转换为小写。 String.ToLower()
方法是一个带有签名 unit -> string
的实例方法。如果它是一个静态 string -> string
方法,您可以像这样在管道中使用它:"MyString" |> String.ToLower
,但由于它是一个依赖于实例内容的实例方法,所以这是行不通的。
我知道有一些方法可以解决这个问题,例如使用 "MyString" |> String.map (fun x -> Char.ToLower(x))
或定义方法 stringLower (input: string) = input.ToLower()
,但我对直接在管道。
从上面重申,我并不是简单地要求一种将字符串转换为小写的方法。我在问是否有在管道中使用实例方法的通用方法。
"MyString" |> (fun x -> x.ToLower())
这是个人意见,但我觉得如果你想在管道中使用实例方法,为结果定义一个新变量总是更具可读性before操作然后直接使用实例方法。为什么不直接使用?
"MyString".ToLower()
以上是一个非常简单的案例,但假设您的实际用例是这样的:
let greeting =
[| "hi"; "there" |]
|> String.concat " "
|> fun x -> x.ToUpper()
在这里,有些人更喜欢在管道中使用 ToUpper
以这种方式编写代码。不过我不会这样做,只会写:
let greetingLow = [| "hi"; "there" |] |> String.concat " "
let greeting = greetingLow.ToUpper()
当通过管道传递的事物的类型发生变化时(例如,从这里的数组到字符串),这种事情经常发生。发生这种情况时,我发现打破管道更具可读性。
如果您经常使用某些功能,可以在模块中定义它们
[<RequireQualifiedAccess;
CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module String =
let inline toUpper (s: string) = s.ToUpper()
然后在管道中写入
let greeting =
[| "hi"; "there" |]
|> String.concat " "
|> String.toUpper
缺点是您需要围绕现有实例方法编写精简包装器,并且还需要考虑重载。但是已经有为您定义它们的库(例如 F#+)
有一个 suggestion 用于简化 属性 管道中的访问和方法调用。它原则上获得批准,但甚至还没有 RFC。它允许写类似
的东西
[| "hi"; "there" |]
|> String.Join(' ', _)
|> _.ToUpper(CultureInfo.CurrentCulture)
是否可以在 F# 的管道中直接使用实例方法?我问的是一般情况,但这里有一个例子。
假设我试图在管道内将字符串转换为小写。 String.ToLower()
方法是一个带有签名 unit -> string
的实例方法。如果它是一个静态 string -> string
方法,您可以像这样在管道中使用它:"MyString" |> String.ToLower
,但由于它是一个依赖于实例内容的实例方法,所以这是行不通的。
我知道有一些方法可以解决这个问题,例如使用 "MyString" |> String.map (fun x -> Char.ToLower(x))
或定义方法 stringLower (input: string) = input.ToLower()
,但我对直接在管道。
从上面重申,我并不是简单地要求一种将字符串转换为小写的方法。我在问是否有在管道中使用实例方法的通用方法。
"MyString" |> (fun x -> x.ToLower())
这是个人意见,但我觉得如果你想在管道中使用实例方法,为结果定义一个新变量总是更具可读性before操作然后直接使用实例方法。为什么不直接使用?
"MyString".ToLower()
以上是一个非常简单的案例,但假设您的实际用例是这样的:
let greeting =
[| "hi"; "there" |]
|> String.concat " "
|> fun x -> x.ToUpper()
在这里,有些人更喜欢在管道中使用 ToUpper
以这种方式编写代码。不过我不会这样做,只会写:
let greetingLow = [| "hi"; "there" |] |> String.concat " "
let greeting = greetingLow.ToUpper()
当通过管道传递的事物的类型发生变化时(例如,从这里的数组到字符串),这种事情经常发生。发生这种情况时,我发现打破管道更具可读性。
如果您经常使用某些功能,可以在模块中定义它们
[<RequireQualifiedAccess;
CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module String =
let inline toUpper (s: string) = s.ToUpper()
然后在管道中写入
let greeting =
[| "hi"; "there" |]
|> String.concat " "
|> String.toUpper
缺点是您需要围绕现有实例方法编写精简包装器,并且还需要考虑重载。但是已经有为您定义它们的库(例如 F#+)
有一个 suggestion 用于简化 属性 管道中的访问和方法调用。它原则上获得批准,但甚至还没有 RFC。它允许写类似
的东西 [| "hi"; "there" |]
|> String.Join(' ', _)
|> _.ToUpper(CultureInfo.CurrentCulture)