我在Python中有这段代码:
def f(x, y):
# do something...
return f
我正在尝试用Swift编写此代码,但无法弄清楚是否可行。返回类型将无限长。
这是我试图用Python编写的游戏的一部分。这是一个骰子游戏,具有多个注释功能,每一轮都会被调用。每轮结束后,注释函数可能会返回自身,但也会进行一些更改(例如更改封闭范围中的变量)。
def say_scores(score0, score1):
"""A commentary function that announces the score for each player."""
print("Player 0 now has", score0, "and Player 1 now has", score1)
return say_scores
def announce_lead_changes(previous_leader=None):
"""Return a commentary function that announces lead changes."""
def say(score0, score1):
if score0 > score1:
leader = 0
elif score1 > score0:
leader = 1
else:
leader = None
if leader != None and leader != previous_leader:
print('Player', leader, 'takes the lead by', abs(score0 - score1))
return announce_lead_changes(leader)
return say
def both(f, g):
"""Return a commentary function that says what f says, then what g says."""
def say(score0, score1):
return both(f(score0, score1), g(score0, score1))
return say
def announce_highest(who, previous_high=0, previous_score=0):
"""Return a commentary function that announces when WHO's score
increases by more than ever before in the game.
assert who == 0 or who == 1, 'The who argument should indicate a player.'"""
# BEGIN PROBLEM 7
"*** YOUR CODE HERE ***"
def say(score0,score1):
scores = [score0,score1]
score_diff = scores[who]-previous_score
if score_diff > previous_high:
print(score_diff,"point(s)! That's the biggest gain yet for Player",who)
return announce_highest(who,score_diff,scores[who])
return announce_highest(who,previous_high,scores[who])
return say
# END PROBLEM 7
重复播放功能,直到某个玩家达到分数为止
def play(strategy0, strategy1, score0=0, score1=0, dice=six_sided,
goal=GOAL_SCORE, say=silence):
"""Simulate a game and return the final scores of both players, with Player
0's score first, and Player 1's score second.
A strategy is a function that takes two total scores as arguments (the
current player's score, and the opponent's score), and returns a number of
dice that the current player will roll this turn.
strategy0: The strategy function for Player 0, who plays first.
strategy1: The strategy function for Player 1, who plays second.
score0: Starting score for Player 0
score1: Starting score for Player 1
dice: A function of zero arguments that simulates a dice roll.
goal: The game ends and someone wins when this score is reached.
say: The commentary function to call at the end of the first turn.
"""
player = 0 # Which player is about to take a turn, 0 (first) or 1 (second)
# BEGIN PROBLEM 5
"*** YOUR CODE HERE ***"
scores = [score0,score1]
strategies = [strategy0,strategy1]
while score0 < goal and score1 < goal:
scores[player] += take_turn(strategies[player](scores[player], scores[other(player)]),
scores[other(player)], dice)
swap = is_swap(scores[player], scores[other(player)])
player = other(player)
if swap:
scores[0],scores[1] = scores[1], scores[0]
score0,score1 = scores[0],scores[1]
# END PROBLEM 5
# BEGIN PROBLEM 6
"*** YOUR CODE HERE ***"
say = say(score0,score1)
# END PROBLEM 6
return score0, score1
答案 0 :(得分:8)
让我们尝试写这样的东西。
CREATE PROCEDURE GetMatches(@input varchar (100))
AS
BEGIN
WITH CTE AS
(
SELECT value AS number
FROM STRING_SPLIT(@input, ',')
)
SELECT CTE.number, A.ColumnName
FROM A
INNER JOIN CTE
ON ',' + A.ColumnName + ',' LIKE '%,' + CTE.number + ',%';
END
现在,编译器会抱怨,因为EXEC dbo.GetMatches @input = '101,104';
在声明返回内容时未声明返回任何内容。
好吧,让我们尝试添加一个返回值类型,即不接受任何参数且不返回任何内容的闭包。
func f() {
return f
}
现在,编译器抱怨f
是func f() -> (() -> ()) {
return f
}
,因此无法转换为f
。
我们应该编辑声明以返回() -> (() -> ())
,对吧?
() -> ()
现在() -> (() -> ())
成为func f() -> (() -> (() -> ())) {
return f
}
,无法转换为f
!
现在看到图案了吗?这将永远持续下去。
因此,您只能以类型不安全的方式执行此操作,并返回() -> (() -> (() -> ()))
:
() -> (() -> ())
用法:
Any
之所以可以在python中实现,恰恰是因为Python的类型很弱,您无需指定返回类型。
请注意,我不鼓励您使用Swift编写此类代码。在Swift中进行编码时,请尝试以Swift的心态解决问题。换句话说,您应该考虑另一种解决问题的方法,该方法不涉及此类功能。
答案 1 :(得分:2)
也许不是您想要的,但是您可以对闭包进行类似的操作
typealias Closure = (Int) -> Int
func doStuff(action: @escaping Closure, value: Int) -> Closure {
let x = action(value)
//do something
return action
}
答案 2 :(得分:2)
好吧,实际上您可以在Swift中执行类似的操作,只需要将代码的线性部分与递归分开,并将递归代码包装在struct
中即可:
// Recursive code goes here:
struct Rec<T> {
let call: (T) -> Rec<T> // when code `from outside` calls it, it will execute linear part and return recursive
init(closure: @escaping (T) -> Void) { // create new loop with linear `closure`
self.call = {
closure($0) // execute linear code
return Rec(closure: closure) // return recursive wrapper
}
}
subscript(input: T) -> Rec<T> { // this exist just to simulate `f(x)` calls, using square brackets notation
return self.call(input)
}
}
// Linear code goes here
let sayScores = Rec { (score0: Int, score1: Int) in
print("Player 0 now has", score0, "and Player 1 now has", score1)
}
用法:
let temp = sayScores.call((1, 2)) // will print: Player 0 now has 1 and Player 1 now has 2
temp[(0, 0)][(10, 42)] // temp is `Rec<(Int, Int)>`
// will print:
// Player 0 now has 0 and Player 1 now has 0
// Player 0 now has 10 and Player 1 now has 42
因此您可以使它工作,但是我不知道您是否应该在Swift中使用它。